Deploying with Dokku
A big part of being agile is getting our projects out of our development machines and onto the web, where customers, users, and testers can see, touch, and feel them… and most importantly, provide feedback not just on mockups and screenshots, but from actually using the product. It’s not infrequent to prototype a site or microservice in the morning and get it deployed for testing the same afternoon. Our deployments are made much simpler due to an open source technology called Dokku.
We deploy a lot of single page applications and node.js services, and Dokku lets us spend more time building our products and less time messing with linux server configuration.
What is Dokku?
According to its Github readme, Dokku is “A docker-powered PaaS that helps you build and manage the lifecycle of applications”. In simpler terms, it’s software that runs on your server and makes deployment easy by handling the movement of source code, containerization of sites, assignment of domains, builds, SSL certs, and more. (It’s very similar to the service Heroku, but you can install and run it on your own infrastructure)
Dokku is designed to host multiple sites on the same server right out of the box. In Dokku parlance, these are called “apps”, and creating a new one is a simple command in the terminal.
dokku apps:create {appname}
Behind the scenes, Dokku configures git to receive code pushes, creates a subdomain for the app based on its name, and awaits your first push of code.
Deploy with a git push
Since Dokku is designed to work with git, all you need to do is create another remote on your development environment. (If you’ve only ever used a remote called “origin”, this is the use case for others!) .
git remote add dokku dokku@{serveripordomain}:{dokkuappname}
Once that’s set up, a simple push kicks things off…
git push dokku master
Dokku will receive the push, and start checking the code for instructions on how to build and host it.
Building & buildpacks
Dokku builds apps after they are deployed using ‘buildpacks’, or sets of instructions that outline how to build the environment the app will run in. Dokku will auto-detect most node applications, and run the generic node.js buildpack. You can also specify a custom buildpack if you need specific ports exposed, need to download files or move files around, or need to install special dependencies.
Here’s the .buildpacks file for ZoLa, an EmberJS app. It needs a custom Ember buildpack, which you can inspect to see how Dokku will build the environment and run commands.
Docker Containerization
Dokku keeps all of our apps running in Docker containers, so they can’t co-mingle. Each container is built based on the buildpacks described above on every push. When you push new code, Dokku builds a new container while leaving the existing one running. Once the new container is ready, Dokku swaps out the old for the new, and destroys the old container, providing zero downtime!
Containerization and zero downtime updates mean we can deploy updates multiple times per day, and even automate them for continuous integration. For some of our apps, whatever is pushed to Github will also be automatically deployed to Dokku (as long as it passes all of its checks and tests!)
Nginx and Instant Subdomains
Since Dokku is running multiple apps on the same server, it also needs to manage different domains for each one so that they will all be accessible on the web at port 80/443. Dokku manages the nginx config on the server so you don’t have to. Dokku needs a global domain for the server it runs on, and then assigns subdomains automatically when you create an app. All apps are available at http://{appname}.{globaldomain}, Dokku handles the nginx config necessary to route traffic for this subdomain to the appropriate docker container.
Custom domains are easy to add, just create a DNS record for the domain pointing to the Dokku server and run one command:
dokku domains:add {appname} mycustomdomain.com
Absurdly-easy SSL
Thanks to letsencrypt free SSL certs, and the dokku-letsencrypt plugin (did I mention there’s an awesome plugin ecosystem?), adding SSL certificates to Dokku applications couldn’t be easier. With one command, Dokku requests a certificate and configures nginx to use it for a specific domain.
> dokku letsencrypt {appname}
Naturally, all NYC Planning Labs sites and services are served using https.
Dokku Helps Us Move Fast
Dokku is a part of our toolkit that frees up time and resources, allowing us to focus on building products instead of managing infrastructure. It also serves to combine DevOps with Agile, as 18F has outlined as critical in a recent blog post. Some linux admin skills are necessary, but aside from trial and error on the occasional custom buildpack, it just works.
Let us know @nycplanninglabs if you need pointers on getting started, or want to share your Dokku experiences.