Deploy Express.js App with Dokku

Deploying a Node.js application using Heroku is expensive since you need 2 Dynos for it to work flawlessly without crashing when requested by users.

I will highlight the steps you can take to deploy your site with Digital Ocean using Dokku. Dokku is a mini-Heroku with Docker under the hood that let you build using ‘Heroku Buildpacks’ and run your application in separate containers.

If you’re looking for a way to deploy your app using Dokku chances are you know what Node.js is, however, if you don’t know, Node.js is:

Node.js® is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Express.js is a Node.js web application framework, designed for building single-page, multi-page, and hybrid web applications.

Digital Ocean is a cloud hosting solution; they let you spin servers in as little as 5 seconds. We’ll look more at all of these shortly.

Getting Started

Let’s assume you’ve already created your application and you’re ready to test it on your local machine before deploying it; you can use node app.js or nodemon in your CLI.

Nodemon will monitor for any changes in your node.js application and automatically restart and run the server. It’s just perfect for development.

If you open your browser and type http://localhost:3000 you should see your application. You can stop your application using control + c (that’s if you’re on a Mac).

Create a Digital Ocean Droplet

Again, let’s assume you have an account already, but in case you still don’t have one, you can create your account (using this link gets you a $10 credit, which is good for two months to host a simple application).

Digital Ocean

Digital Ocean

Digital Ocean

Digital Ocean

Digital Ocean

Digital Ocean

Time to Deploy

Deploying to Dokku is super easy. We just need to git push to a particular remote. First, we need to make our project a Git repository. In your terminal, type:

git init

This will create a repository in our project directory. Next, you have to create a new file called .gitignore and add:

node_modules

CHECKS and app.json

You need to create a file called CHECKS inside your application root directory and add these inside it:

WAIT=10
ATTEMPTS=6
/check_deploy.txt deploy_successful

You should now create check_deploy.txt inside your public directory.

Additionally, you will need another file called app.json inside your app’s root directory as well. Paste all of these inside it:

{
  "name": "example",
  "description": "Bla bla about your application",
  "keywords": [
    "dokku",
    "node",
    "example.com"
  ],
  "buildpacks": [
    {
      "url": "https://github.com/heroku/heroku-buildpack-nodejs"
    }
  ],
  "scripts": {
    "dokku": {
      "predeploy": "touch /app/predeploy.test"
    }
  }
}

You can define postdeploy as well under Dokku Script, but postdeploy changes will NOT be committed to the application image. That said; you don’t really need it.

This will make sure we don’t copy node modules with our code unnecessarily, as Dokku will install any dependencies that are needed. Now, back in your terminal, type the following commands:

git add .
git add Procfile
git commit -m "initial commit"
git remote add dokku [email protected]:example
git push dokku master

The first line adds the files to be committed; then you add a Procfile which Dokku needs to initiate your app. Next we add a remote called dokku at the location [email protected]:example. In this case, dokku@ refers to the user dokku on our server, in my case example.com. The :example is the name of my app. You can have multiple applications on the same server, so naming each one is important.

Now, you can review the output if you want. You can now see your application by visiting example.com.

Watch out for…

You need to map your proxy with the port otherwise you will keep getting net::ERR_CONNECTION_REFUSED when you try to access the site. You can configure your setup with dokku proxy:ports-add example http:80:5000 commands to solve this issue.

In Dokku 0.5.0, port proxying was decoupled from the nginx-vhosts plugin into the proxy plugin. Dokku 0.6.0 introduced the ability to map host ports to specific container ports. In the future this will allow other proxy software - such as HAProxy or Caddy - to be used in place of nginx.

$ curl http://example.com:80
curl: (7) Failed to connect to example.com port 80: Connection refused

$ dokku proxy:ports-add example http:80:5000
-----> Setting config vars
       DOKKU_PROXY_PORT_MAP: http:80:5000
-----> Configuring example.com...(using built-in template)
-----> Creating http nginx.conf
-----> Running nginx-pre-reload
       Reloading nginx

$ curl http://example.com
Hello World!

$ curl http://example.com:80
Hello World!

$ dokku proxy:ports example
-----> Port mappings for example
-----> scheme             host port                 container port
http                      80                        5000

I hope this will help someone to deploy their Node.js application with Digital Ocean using Dokku. If you have any questions, you can always send me an e-mail.

🤓