Ruby on Rails Deploy Explained: Deploy to Dokku
This article is the third from the Ruby on Rails deploy explained series. In the previous article we set our application to conform to the 12 factor rules and now it can be easily pushed to Heroku, or, as shown in this guide, – to Dokku - your own, cheap and fairly fancy PaaS.
There are a lot of tutorials for that. However, I'll try to give you some instructions beyond them and touch all the gotchas.
It's better if you already have the domain name. If you don't, it would be nice to know what it can be. In the latter case, you can temporary add it to
Now, pick up a hosting account on Digital Ocean or anywhere else and let's go. First of all, get an instance with 2GB RAM or more. If you choose a droplet with less than 2 GB of RAM you may experience troubles with it. Fortunately, it's not expensive. I suggest you to:
- Use your FQDN as a hostname for that instance.
- Do not take predefined Dokku image unless you just want to play.
- Use Ubuntu 14.04 x64.
- Uncheck IPv6 checkbox on Digital Ocean, because there are some known issues with IPv6 on Digital Ocean and Docker.
Log in to your droplet via ssh:
$ ssh email@example.com
I used to install dokku-alt - a main fork of the original dokku. But a lot of problems in upstream have been fixed and upstream seems to be much better maintained at present. So we'll use the main one.
To install it, run:
$ wget https://raw.github.com/progrium/dokku/v0.4.0/bootstrap.sh $ sudo DOKKU_TAG=v0.4.0 bash bootstrap.sh or whatever version is the latest now
At the end the script will suddenly hang and will suggest you to open browser at some URL. Ignore it and hit Ctrl+C.
For Amazon Linux users
I have mentioned, that you should use Ubuntu. So, in your case it will look like installed but you will run out of free space on disk very fast.
Dokku works on Docker (which will be explained later) and Docker uses a copy-on-write file system. By default, it brings AUFS with it but requires a kernel rebuild. You may not like this or you may not have such an option, for example, on Amazon Linux. But there is a good alternative for you: use BTRFS. This section is about YMMV, so I leave you with that wiki. Come back!
On Digital Ocean, as well as on many other cloud providers, swap is disabled by default. If you took a box with less than 2GB, you may run out of memory. I advise you to enable swap: execute the following (it will create 512MB swap file and you can adjust it as you want):
cd /var touch swap.img chmod 600 swap.img dd if=/dev/zero of=/var/swap.img bs=1024k count=1000 mkswap /var/swap.img swapon /var/swap.img free echo "/var/swap.img none swap sw 0 0" >> /etc/fstab
Place the initial configuration:
$ cd /home/dokku $ echo "yourdomain.com" > VHOST $ echo "yourdomain.com" > HOSTNAME
The first domain is the one which is used in nginx vhost configurations and it is very important. The second - is just a domain name that will be used for newly deployed applications by default.
Install needed plugins
In practice, the database is necessary. What does your app require – Postres, MySQL, MariaDB, Redis...? Check the plugin list and install whatever you need. For instance, Postgres:
$ dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
Now put your ssh key there:
locally $ cat ~/.ssh/id_rsa.pub | ssh firstname.lastname@example.org "sudo sshcommand acl-add dokku $USER"
Time to deploy!
Your app is ready, Dokku is ready and now deploy goes like a breeze.
$ git remote add staging email@example.com:staging or production $ git push staging master
staging at the end of line works as an application name in dokku. I highly encourage you to have the same name for git remote and for app name. Your app will be available at
Talk to dokku
Dokku installs fairly special
.ssh/authorized_keys so that you can call dokku commands from your local machine. To do this, log in via ssh to the machine as a dokku user. For example:
$ ssh firstname.lastname@example.org apps:list locally is an equivalent to $ dokku apps:list on remote server
You may also want to look at Dokkufy.
From here, I'll provide commands as
dokku something, assuming that you know how to run them from your developer machine.
There is no doubt that your app has a database. After the first deployment it will most likely fail. This can be easily fixed if you have installed a database plugin on an appropriate step. For Postgres:
dokku postgres:create staging-database dokku postgres:link staging-database myapp dokku run staging rake db:create db:migrate
That's it. And check your app, at this point it works.
Do you remember that you moved it to environment variables? Now you can provide such variables for the process:
dokku config:set staging STRIPE_API_KEY=somesome STRIPE_API_SECRET=secretsecret
Periodical tasks, cron
Some options here:
I'd stick with Sidetiq.
Use top-level domain
It is easy, as it is:
$ dokku domains:set staging yourdomain.com
You can even use another domain if it is pointing to the same server: either via A or via CNAME.
You already saw
$ dokku run staging rake db:migrate $ dokku run staging rails console it will run interactively
You can do much more: run
dokku without arguments and learn. A useful thing is:
$ dokku logs staging -t
Redeploy/deploy for new developers
Once on your machine $ curl https://github.com/new-developer.keys | head -1 | ssh email@example.com "sudo sshcommand acl-add dokku <new-developer>" Once on new developer machine $ git remote add staging firstname.lastname@example.org:staging The deploy/redeploy $ git push staging master
With Dokku, you can deploy application by yourself without much knowledge and without involving an admin. You may control all aspects of the setup, have proper tools to monitor everything and be happy.
Later on, we will discuss how it works, how to scale it and other interesting things.