Dokku is dev ops for dummies and a cheaper alternative to Heroku. Recently I’ve migrated a couple of my projects to it. In this tutorial, I will describe how to setup and migrate a Rails app to Dokku with PostgreSQL, Sidekiq, Redis and Let’s Encrypt or Cloudflare for free SSL.
This tutorial is based on Dokku version 0.28.4. For a more in-depth tutorials, you can check out Dokku docs. I will focus on things you need to get up and running quickly. This blog post assumes you already have a Rails app running on Heroku.
Initial setup
You need to start with purchasing a barebones VPS and adding an SSH access to it. I will not elaborate on how to do it in this tutorial.
I use a Hetzner Cloud VPS, but there should be no much difference in setup process for different providers.
Let’s assume that your VPS has an IP address 192.192.8.8
and your Rails app will use my-rails-app.com
as a domain.
SSH into your VPS:
and run:
Next, you need to specify your app name:
You also need to add Dokku plugins we will use for our Rails app:
Now you need to configure your public SSH key to be accepted by Dokku remote by running:
You can find the contents or your public key on GitHub:
https://github.com/[YOUR GITHUB USERNAME].keys
You can now exit your VPS. All the remaining commands can be executed locally.
Setup Dokku remote target
The same as with Heroku, Dokku deploys are performed automatically when you push code changes to a remote repository. To set it up you need to add following lines to your .git/config
file.
You can validate if the setup was successful by running:
Deploy will fail at this point. Just make sure you can access the VPS with your Dokku SSH keys.
Copy Heroku environment variables
You probably have a bunch of environment variables setup in your Rails Heroku app. To list them just type:
For most of the variables you need to run the following command:
Just don’t copy the values of DATABASE_URL
and REDIS_URL
we will set those in the next step.
Setup Postgres and Redis
With Dokku each of the services will be running in seperate Docker container. Dokku abstracts away all the logic of how containers work with a high-level API. To add Redis and PostgreSQL linked containers to your Rails app you just have to:
This will set DATABASE_URL
and REDIS_URL
environment variables for your Rails app. You can try to run:
again now and your app should be up and running on Dokku.
Dokku uses the same Procfile format as Heroku. If your app uses a worker process (eg. Sidekiq) don’t forget to initialize it by running:
This is a Procfile for a Rails app running on Puma with Sidekiq:
Automatic backups to Amazon S3
You probably want to backup your data. Setting up an automated backup schedule to Amazon S3 is as simple as configuring AWS credentials:
and adding the following line to /etc/crontab
Deployment hooks
You could run a database migration manually after each deploy or integrate it into the process. To do it add an app.json
file to the root of your project:
Setup Domains and SSL
Before you disconnect your domain from Heroku you can work with a local override by modifying /etc/hosts
file. Add the following line:
Now execute this command:
You should be able to access your Dokku Rails app via a browser now. It is not yet exposed to the world and does not support https
connections.
Add SSL with Let’s Encrypt
Let’s Encrypt let’s you add a free SSL/TLS protection to your websites. Enabling it for Dokku apps is as simple as running:
That’s it. Your certificate file should be installed on NGINX and automatically renewed using CRON task every 2 months.
Remember that you can run those commands only after your domain has already been redirected to Dokku VPS on a DNS level. Otherwise, domain ownership validation will fail.
Add SSL with Cloudflare
Alternatively, you can use Cloudflare to add a free SSL to your website. You can check out my other post for more info about it.
Once you setup SSL in Cloudflare panel you need to install certificate files on your server. Dokku offers a tool to do it. You will need two files certificate.crt
and certificate.key
. Both can be downloaded from Cloudflare.
I had problems with adding certificate files without making a tar package out of them. To make a tar package and add the certificates run:
That’s it. Your app should be running with a secure connection now.
Heroku PostgreSQL data migration
Now that your Dokku app is active you can migrate your production data there. This is a part when you will have a downtime for your app so you might want to try the process out in a staging environment first. Downtime duration is dependent on your data size.
First, you should turn on the maintenance mode on Heroku:
then disable all the processes so that they don’t modify data:
next, create an up to date backup and download it:
Now you can load the data into a Dokku database:
Now you just need to change your DNS entries for a domain to start pointing to Dokku VPS server. That’s it. The migration from Heroku is over.
Useful Dokku commands
I am no dev ops pro and this post just scratches a surface of what can be done with Dokku. For more info you should check out documentation of Dokku and plugins I’ve mentioned:
Below I list a bunch of commands I use daily when working with Dokku apps:
Caveats
Long deploy process
Problem with Dokku is that deploys take much longer than in case of Heroku. For a simple Rails app, it is something around 2 minutes. I also have a bit more complex app which is dependent on both Ruby and Webpack with NodeJS and its deploy process takes around 5 minutes.
It could be a fault of my VPS provider and its slow internet connection or CPU. I know there are some hacks to speed up building a release from a buildpack with caching but I did not look into it yet.
I ended up using Heroku free instances with its quick deploy cycles for staging environment. That’s where I deploy often during development. Occasional longer production deploy is ok for my workflow.
[Update] there is a better way to optimize Dokku deployment speed using Dockerfile. Check out my new blog post.
Single server infrastructure
Limitation of Dokku is that it supports only one server. If you need a fancy production infrastructure with multiple server instances behind a load balancer it is not a tool for you.
You can always scale Dokku vertically so for less complex cases, side-projects etc. it could be an optimal choice.
Summary
Throughout my career, I have never been too much into dev ops stuff. I have either used Heroku or had a dedicated specialist in the team.
With Dokku I was surprised how simple it was to use even if you don’t have much dev ops experience. You should definitely give it a try if you are hosting your side-project on Heroku and overpaying for it. Migrating Abot - Slack Anonymous Feedback allowed me to reduce its infrastructure costs from $16 to $3 a month.