How to automate deployment of your Node + Express app to Digital Ocean using CircleCi

Allan Mogusu
Nov 5 · 8 min read

Hello folks! So today i’ll teach you how you can continuously deploy your Node.js + Express app to Digital Ocean using CircleCi as your test runner.

Digital Ocean is one among many cloud infrastructure providers that essentially provide developers with services to deploy and scale their applications.

This tutorial assumes that you have a Digital Ocean account. If you do not have one, you can create it by signing up on their website here.

Setting Up the Digital Ocean droplet with SSH

Your account created, proceed to provision your Ubuntu machine, by clicking on the New Projects option on the dashboard. Enter the name of your project and optionally a description. Select the web application option under the ‘Tell us what this is for’ field. Then click the Create Project button.

Since we’re not interested in moving droplets, or any resources, we’ll skip the second option by clicking on the Skip for now text.

In the screen that appears next, create your droplet by clicking on the Get Started With a Droplet button, you should then receive a screen similar to the one below.

DigitalOcean Droplets are Linux-based virtual machines (VMs) that run on top of virtualized hardware. ~ Digital Ocean docs

For the purpose of this tutorial, we’ll choose the Ubuntu distro , the standard plan and New York as our default data center region. In the authentication part we’ll choose SSH-KEYS because SSH gives us the flexibility of accessing our remote resources without password access.

If you do not have an SSH key you can generate one by clicking on the New SSH key button, which will give you instructions on how to generate your SSH-KEY. In a nutshell, on your local machine open your terminal and run the command ssh-keygen . This command generates a public/private RSA key pair that will be used to authenticate login on your remote server on Digital Ocean. Below, I have provided a path and naming for my key i.e /Users/allanmogusu/.ssh/id_rsa_tutorialsince I already have a key with the name id_rsa .

Copy your key to the clip-board with pbcopy < ~/.ssh/id_rsa_tutorial.pub . If that does not work for you, you can do cat ~/.ssh/id_rsa_tutorial.pub and manually copy the contents of what is printed out on your terminal.

Navigate to your Digital Ocean page and click on the Add SSH key button, and paste your key in the text area as shown below. Give a name to your key and click Add SSH Key to save. Your SSH-key will be picked up.

Paste your public SSH key to text area and add
Your SSH key is picked up by Digital ocean

Scroll to the bottom and provision your droplet by clicking on the Create Droplet button.

Your droplet is created successfully. You can now SSH into the container by running this command on your local machine’s terminal. Replace my path with the path to the key you created earlier. and IP_ADDRESS_OF_DROPLET with the IPv4 address of the droplet you’ve created as shown in the screenshot.

ssh -i /path/to/.ssh/id_rsa root@IP_ADDRESS_OF_DROPLET

SSH-ing into my droplet with the tutorial RSA key created earlier

Once you SSH into your droplet, install node.js, npm and forever.js

$ sudo apt-get update
$ sudo apt install nodejs
$ sudo apt install npm
$ npm install -g forever

We install forever.js as shown above so that it will keep our node script running in the background once the SSH session is terminated.

Setting up the express app

We have successfully setup our droplet with SSH. For the purpose of this tutorial we’ll be deploying Robien Wieruch’s basic express REST API.

Clone the repo as shown below then install dependencies:
$ git clone https://github.com/rwieruch/node-express-server-rest-api.git TutorialApp

$ cd TutorialApp && npm install

Start the app:

$ npm start

Let’s make a request to see if all is well. On your terminal, run the curl command below:
$ curl -X POST -H “Content-Type:application/json” http://localhost:3000/messages -d ‘{“text”:”Hi again, World”}’

You should receive a response similar to the one shown above.

We will now create a new repo on Github then add it as a remote for our express app by running the highlighted commands in your terminal:

create a new repo on Github and copy the highlighted commands

$ git remote add origin https://github.com/Allan690/Tutorial-Deployment.git
$ git push -u origin master

You will get an error when you try adding the origin. Remove the git remote that is already set by running git remote rm origin then re-run the above commands.

Setting up Github with CircleCi

With our app pushed to Github we will now add it to CircleCi. This tutorial assumes you have an account with CircleCI. If you don’t have one, just create an account with them here.

Once logged in, Set up your project to use CircleCI

Choose Linux as the environment and Node as the language.

We’ll go back to the root of our local tutorial app folder and create a config.yml file inside a .circleci folder by running the command:

$ mkdir .circleci && touch .circleci/config.yml

Copy the contents in the gist below to your config.yml file

We’ll commit our changes and force push the master branch with the latest changes so that CircleCI can build successfully.

$ git add .

$ git commit -m "added config.yml"

$ git push -f

CircleCI should now show your build to be passing.

We will then add the CircleCi markdown badge to our repo’s readme and push again. You can access the badge under the settings of your project in CircleCi.

Linking CircleCI with our droplet/remote server

Having setup our Github connection with CircleCi, we can then proceed to setup the means by which CircleCi and our remote server will communicate. This will be done over SSH. To do this, on your local machine, SSH into the droplet you created as earlier shown.

$ ssh -i /Users/allanmogusu/.ssh/id_rsa_tutorial root@DROPLET_IP_ADDRESS

Inside our droplet’s bash terminal we’ll generate a secure RSA key in the PEM format without a password as shown below:
$ ssh-keygen -m PEM -t rsa -C “your_email@example.com”

It is very important that you should not protect your key with a password when setting it up because CircleCi cannot currently work with SSH keys that are password protected.

Add your generated key to the authorized_keys file by running the command below. Substitute id_rsa.pub with the name of your public key.

$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

The >> operator appends the contents of our generated public key to the authorized_keys file.

We’ll now copy the private key to the clipboard then add it to CircleCi.

$ cat ~/.ssh/id_rsa

Under the Permissions section in CircleCi click on SSH Permissions and add your SSH key by clicking on the Add SSH Key button and pasting your private key in private key section as shown below.

A successful addition should generate a fingerprint as shown below:

With this, we are able to SSH into our remote machines using CircleCI.

Setting up deployment scripts

Modify the config.yml file as follows, add these steps

- add_ssh_keys:
fingerprints:
- "04:58:f8:ac:82:c2:8a:60:e8:ec:7b:1b:42:84:a9:59"
- deploy:
name: deployment
command: ssh -o "StrictHostKeyChecking no" root@165.227.114.98 "cd ~ && rm -rf TutorialApp && git clone https://github.com/Allan690/Tutorial-Deployment.git TutorialApp && cd TutorialApp && sh post_deployment.sh "

The add_ssh_keys step adds the fingerprint of the private key which we added to CircleCi.

The deploy step creates an SSH connection with our remote server then runs a series of commands. It removes the existing TutorialApp folder and re-clones the repo. It then moves into the directory and runs a bash script to start the app.

At the root of the directory add the post_deployment.sh file:

$ touch post_deployment.sh

Add the following in the file:

#!/bin/bashecho ‘installing requirements…’ npm installecho ‘start server…’forever start -c “npm start” ./echo ‘started server. ending SSH session..’exit

Create a branch off master , commit the changes and push to Github. On Github you can then create a pull request and merge it to master to trigger a CircleCi build. Your build should pass and the app should deploy

$ git checkout -b deploy-branch && git add .
$ git commit -m "setting up deployment"
$ git push -u origin deploy-branch

To check whether our deployment worked, we can SSH into our remote server via our local machine and check the logs of the forever process to see if our node.js app is running in the background:

$ ssh -i /Users/allanmogusu/.ssh/id_rsa_tutorial root@DROPLET_IP_ADDR

$forever logs 0

forever logs showing that my app is running on port 3000 on the background

With that we have been able to deploy a Node.js + Express app to a Digital Ocean cloud droplet. Feel free to leave your questions, comments and suggestions, and a clap :). Thanks.

Allan Mogusu

Written by

Interested in solving real problems..

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade