// Tutorial //

How to Host a Node.js App on Digital Ocean

Draft updated on Invalid Date
Default avatar
By Chris Ganga
Developer and author at DigitalOcean.
How to Host a Node.js App on Digital Ocean

This tutorial is out of date and no longer maintained.

Warning: For the latest information, refer to the documentation for creating DigitalOcean Droplets.

Introduction

DigitalOcean is a cloud computing platform that offers developers a Solid State Drive (SSD) to do whatever they want. Sounds fun.

DigitalOcean is a simple and robust cloud computing platform, designed for developers.

Once you have this SSD, you have access to rich APIs to access the Droplet, networking for your droplet, and Storage to attach to your Droplet.

They also provide you with a couple of Server Operating Systems, which you use to start up your Droplet.

This approach has led to the development of some pre-built images or apps, such as WordPress and the Ghost blogging platform, that can be installed in one click.

Hosting Approach

We’ll look at two ways of Hosting a NodeJS app to DigitalOcean.

  1. We’ll first write our app locally, push it to GitHub, then pull it from within our DigitalOcean Droplet.
  2. We’ll dockerize our Node.js application and deploy it to DigitalOcean using Docker-Machine.

Sample Node App

Since we are looking at deployment, we’ll keep things simple. We’ll just have a simple express server telling us where the magic happens.

If you already know how node apps work, especially with Express, you can skip this part, and just head to the Setting Up DigitalOcean part since we’ll clone the Node.js app from a GitHub repo.

Create a directory called DO-node, and inside initialize npm, then create a file, index.js:

  1. mkdir DO-node
  2. cd DO-node
  3. npm init -y
  4. npm install --save express
  5. touch index.js

The package.json file created should look something similar to this.

{
  "name": "node-do",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.14.0"
  }
}

Write a simple express server that tells us where the magic happens. I pulled this one directly from the Express documentation.

var express = require('express')
var app = express()

app.get('/', function (req, res) {
  res.send('Hello DigitalOcean!')
})

app.listen(3000, function () {
  console.log('Magic is happening on port 3000!')
})

If we run:

  1. npm start

We should see the terminal with Magic is happening on port 3000! and opening the browser http://localhost:3000 should display the message Hello DigitalOcean!.

Next, you can create a GitHub repository and push this code, or just move on with the one I’ve created.

If you chose to create your own repo, copy the GitHub URL, then run this.

  1. git init
  2. git remote add <YOUR GITHUB REPO>
  3. echo "node_modules/" > .gitignore
  4. git add .
  5. git commit -m "initial commit"
  6. git push origin master

Here we create a git repo, then create a .gitignore file and add in node_modules so that it’s ignored. We then add everything with git add . and push it to the GitHub repo.

Setting up DigitalOcean

First of all, you need a DigitalOcean account. Head over to DigitalOcean and Sign up for an account.

Once you enter your details, you will receive a confirmation email, that will help you complete the signup process.

You need at least $5 to be able to complete the Signing Up process. You can either add your Credit Card or use PayPal.

At the time I’m writing this, if you are a student, you can get the GitHub Student Pack, which has a $50 worth credit for DigitalOcean to get you started with hosting in DigitalOcean.

Once you’ve signed up, and have $5 or above in your account, we should be good to go.

Creating a Droplet.

There are two ways to create a Droplet in DigitalOcean. You can do it with the DigitalOcean Control Panel, or using the DigitalOcean API. We’ll cover the latter one on the second deployment with Docker Machine.

When you log in to your DigitalOcean account you should see a Create Droplet button.

To see how much credit you have, you can click on the arrow next to your avatar on the far right, then click on settings, and click on the billing section on the left.

Once you are good to go, click on the Create Droplet Button. You will be taken to this page:

You’ll see we have three tabs

  1. Distributions refers to Linux distros that we can install into the new droplet we are about to create. In this case, we see Ubuntu, FreeBSD, Fedora, Debian, CoreOs, and CentOS. Note that all these are the Server Versions of these distros.
  2. One-click apps refers to images already built with support for some common software. If you click on the tab, you’ll see common application platforms such as Django, MEAN, WordPress, Drupal, and even Docker. This installs all the dependencies required to run these apps, unlike the first distributions where we’ll have to install everything manually.
  3. Snapshots refers to droplet images we’ve built before, and we’d like to create another Droplet based on them.

So click on the One-click apps section, and select the NodeJS 6.9.2 on 16.04 which means Node.js on Ubuntu 16.04.

Head to the next section. To choose a size.

Choose the $5 per month ($5/mo) option on the Standard tab. This option has 512 MB RAM and 20GB SSD which should be enough for this article.

The next section is Add Block Storage which we can ignore for now.

Next, choose a region close to where you are. Ideally, this should be close to where the users of your app will most likely be.

You can then add Select additional options, but this is not necessary for now.

The next section is the important one. We need to add an SSH key to enable us to access our Droplet remotely.

I have a couple of options because I’ve added SSH keys before.

SSH keys provide a more secure way of logging into a virtual private server with SSH than using a password alone. While a password can eventually be cracked with a brute force attack, SSH keys are nearly impossible to decipher by brute force alone.

Click on the New SSH key option. A Modal will pop up for you to add your SSH key.

You can go through Generating a new SSH key and adding it to the ssh-agent by GitHub.

Note: If you are using Windows, you need to have Git Bash installed. You can do this by downloading git for Windows, and enabling the Git Bash option during installation.

But it generally involves the following commands

  1. ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Which will then be followed by a couple of questions.

The one thing to note is where the SSH key will be stored. Since you need to copy it.

Once you’ve generated your SSH key, add it by clicking on the New SSH Key button.

Paste in your SSH key and give it a name, then click on the Add SSH Key button.

The new SSH Key will be selected by default.

In the last section, you can choose whether to create more than one Droplet and edit the name of your Droplet. You can leave them as they are, and click on the Create Button.

We’ll see some cool animation there, it should take a few seconds to create your Droplet.

You can see we’ve been assigned an IP address. Which I’ll use for this article and delete after I’m done. So whenever I refer to your Droplet IP address, I’m referring to this address.

If you click on the Droplet, it should take you to the Droplet’s settings and info.

The ON toggle at the top right indicates that our Droplet is running.

Accessing DigitalOcean Droplet

If you generated an SSH key, go to your terminal and access your Droplet with this syntax. If you are using Windows, make sure you are using Git Bash.

  1. ssh <user>@<droplet_ip_address>

So we’ll SSH into our Droplet with this. Remember to replace the IP Address with the one generated for you in the Control Panel:

  1. ssh root@<DROPLET IP ADDRESS>

SSH usually warns you about the authenticity of a new host, so type in yes when you are prompted. You will then be prompted to change your password. DigitalOcean should have sent you a root password in the email. If you did not receive one, just click on the Access tab, then select Reset Root Password.

Once this is done, you should see an Ubuntu terminal.

You can see running ls / lists the root file system of an Ubuntu distro.

Hosting the Node.js app

So we already have our Node.js app on this GitHub repo, or the one that you created.

We used the One-Click apps to set up our Droplet, so we have all the dependencies we need. If we hadn’t done this, we’d have to follow these steps to do it run our app.

  1. Get into our Droplet.
  2. Install git.
  3. Install Node.js.
  4. Clone our repo.
  5. Serve the app.

Now, we can only focus on the last two.

Get into Droplet

Let’s SSH into the Droplet with the IP. Remember to replace the IP with your IP address from the DigitalOcean control panel.

  1. ssh root@<DROPLET IP ADDRESS>

We should have a prompt like this:

root@<droplet_name>:~#

Note: Your terminal may occasionally hang depending on your internet connection because SSH needs to maintain an open connection. In case this happens, just close the terminal, and start again.

Install git and Node.js

We already have these installed. We can just confirm by:

  1. git --version

Output:

Output
git version 2.7.4
  1. node -v

Output:

Output
v6.9.2

Clone repo and start the app

To clone the application:

  1. git clone https://github.com/gangachris/DO-nodejs
  2. cd DO-nodejs
  1. npm install
  2. npm start

This should start the application inside your Droplet. If you open a new tab in your browser and go to <DROPLET IP ADDRESS>:3000, you should see the app running.

Awesome, right.

One problem though, if you close your SSH session, npm will stop and your app will be offline. We need to use something that will ensure our app keeps running.

We’ll use forever. Stop your running app with CTRL+C.

  1. npm install -g forever
  2. forever start index.js

Going to <DROPLET IP ADDRESS>:3000 on the browser should still be running your app. Our app will run forever.

Stopping the app:

  1. forever stop index.js

That was the first approach. Let’s look at the next one.

Docker Machine Approach

Docker is an open-source containerization platform that allows us to run our applications inside containers.

To Dockerize an application, you usually need a Dockerfile, that gives instructions to docker on how to run our applications.

We recently Dockerized an Express App. Feel free to go through it.

In this instance, our app is pretty small. We’ll create a Dockerfile for it.

# Create image from NodeJS base image
FROM node:6

# Clone the repo from GitHub
RUN git clone https://github.com/gangachris/DO-nodejs

# Change working directory to the cloned repo
WORKDIR /DO-nodejs

# Install all the dependencies
RUN npm install

# Expose port
EXPOSE 3000

# Run the application
CMD ["npm", "start"]

I’ve commented on the Dockerfile, to clearly explain each step.

To build this image and test if it works, we need to have Docker installed. If you don’t have Docker installed, Install Docker for your respective platform. To ensure Docker is installed, run:

  1. docker -v

Output:

Output
Docker version 1.12.5, build 7392c3b

To build our app’s image using the Dockerfile, use this syntax:

  1. docker build -t <image_name>:<tag> <directory_with_dockerfile>

So in this case, the command will be.

  1. docker build -t digital-ocean-node:dev .

The dot (.) refers to the current Directory. If you run docker images, you should see the image you just built.

Once the image is built successfully, we run a container based on the image with this syntax.

  1. docker run -d -p <host_port>:<container_port> --name <contianer_name> <docker_image>

In this case, the command will be.

  1. docker run -d -p 3000:3000 --name digital-ocean-container digital-ocean-node:dev

The -d tells docker to run the container in detached mode, so you don’t get stuck inside the container. Running docker ps should list the running containers.

Going to localhost:3000 in your browser should load the app.

Docker Machine

Docker Machine is a tool that lets you install Docker Engine on virtual hosts, and manage the hosts with docker-machine commands.

We have DigitalOcean, which will act as our virtual host.

Since Docker Machine enables running docker on multiple hosts, developers can make and distribute their own plugins for any virtualization technology or cloud provider. Docker Machine comes with some plugins/drivers, including, Amazon Web Services, DigitalOcean, Google Compute Engine. This list shows some of the common Docker Machine plugins.

Make sure you have docker-machine installed by running:

  1. docker-machine -v

Output:

Output
docker-machine version 0.8.2, build e18a919

If not installed, you can go through this installation guide.

Once installed, Instructions for running docker-machine with the DigitalOcean driver can be found here.

The command required has this syntax.

  1. docker-machine create --driver digitalocean --digitalocean-access-token=<api_token> test-this

The test-this part refers to the name we want to give to the virtual Docker host.

From the command, we see that we need a digitalocean-access-token. Go to the API tab in your DigitalOcean account:

Then click on Generate New Token:

Leave the read and write permissions checked. Then click on the Generate New Token button.

Your token should be displayed in the section I’ve blacked out.

Once you have all this, run the command now with the correct parameters. Replace the token section with your API access token.

  1. docker-machine create --driver digitalocean --digitalocean-access-token=<your_api_access_token> digital-ocean-node

This will create a new Droplet in your DigitalOcean Control Panel, once it completes. If it fails, you may have to delete the previous Droplet you created. If you look at your Droplets on DigitalOcean you should see a new one.

Now we need to point our docker installation to use the Virtual Host docker we just installed in our virtual server. Right now if we type in

  1. docker images

We’ll see both the node and the digital-ocean-node:dev image present. When we switch Docker to point to our Virtual Host, we should not see these images, since no image build or pull has been done in the Virtual Host.

To point our Docker to the Virtual Host, first, run this command to see available hosts.

  1. docker-machine ls
NAME                 ACTIVE   DRIVER         STATE     URL                         SWARM   DOCKER
digital-ocean-node   -        digitalocean   Running   tcp://<IP ADDRESS>:<PORT>           v1.12.5

You can see we have a docker-machine-node, which we created earlier. The IP should correspond to the IP address we saw in the DigitalOcean Control Panel.

To see how to change Docker to point to this virtual host, simply run this.

  1. docker-machine env digital-ocean-node
  2. export DOCKER_TLS_VERIFY="1"
  3. export DOCKER_HOST="tcp://<IP ADDRESS>:<PORT>"
  4. export DOCKER_CERT_PATH="/Users/account/.docker/machine/machines/digital-ocean-node"
  5. export DOCKER_MACHINE_NAME="digital-ocean-node"
  6. # Run this command to configure your shell:
  7. # eval $(docker-machine env digital-ocean-node)

We are instructed to run eval $(docker-machine env digital-ocean-node) to point our Docker to the Virtual Host Docker environment. So we run that.

  1. eval $(docker-machine env digital-ocean-node)

Done. Now running docker images should return an empty result since we are pointing to the DigitalOcean Virtual host.

  1. docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

So we need to do a new image build and run a container based on the image.

  1. docker build -t digital-ocean-node:dev .

Now running docker images should give us the images.

  1. docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
digital-ocean-node   dev                 8834fa7b0496        2 minutes ago       658.6 MB
node                 6                   faaadb4aaf9b        11 days ago         655.5 MB

The last thing we need to do is run the container. The only difference from how we ran the container earlier is that we’re going to point the default HTTP port 80 to 3000 from the container so that we can access the container with just the IP address in the browser.

  1. docker run -d -p 80:3000 --name digital-ocean-node digital-ocean-node:dev

Going to your IP that was created for the Droplet should show the app running.

Note: To change your Docker to point back to your localhost, simply run:

  1. eval $(docker-machine env -u)

The -u stands for unset.

Remember to either stop or destroy the Droplets you are not using, since you’ll end up being billed if they are running.

Conclusion

We’ve seen how easy it is to deploy a Node.js app to DigitalOcean. I personally prefer the Docker approach, since updating my app will only involve doing new builds, and running them without ever going to the Control Panel.

The first approach, while it’s also easy, will require you ssh-ing into your Droplet often, unless you set up some continuous deployment platform.

Hope this was helpful.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!