Deploying a Rails app with Dokku, Digital Ocean, a custom domain and SSL
If you’re looking to deploy your web app quickly, but don’t want to go with Heroku check out Dokku. Dokku makes it easy to set up a server and deploy to it using Git. Instead of git push heroku master
it is git push dokku master
. If you use Dokku on a Digital Ocean instance it is even easier to set up.
These are the steps I took to get a Rails web app running with SSL, a custom domain and an easy to use deployment pipeline.
1. Set up Digital Ocean for Dokku
Go to https://www.digitalocean.com/features/one-click-apps/dokku/ and select an instance to setup from Digital Ocean. It costs around $6 USD per month. You’ll want to have 1GB of Ram minimum.
Once that is done you visit the IP address of your new instance in the browser. It will offer to run the web installer. It is important to do that immediately. Otherwise anyone finding the setup page can insert their key.
Additionally I recommend configuring your user on the Digital Ocean instance. First I’d change the root password. More can be found here: https://www.digitalocean.com/docs/droplets/how-to/connect-with-ssh/openssh/
As a next step you can create a new sudo user.
$ adduser username
$ usermod -aG sudo username
Then configure the public key for your new user, so you can ssh onto the box without using root. You can find more details about how to set it up here. This step essentially consists of creating a ~/.ssh/authorized_keys
file for your user and copying your public key into that file. The file should also have the right permissions.
2. Configure Dokku
Now that our Ubuntu box is set up on Digital Ocean as a Dokku droplet we need to configure Dokku so it works with our app.
Assuming you have a Ruby on Rails application called my-rails-app
with a Postgres database these are the steps:
$ dokku apps:create my-rails-app # Create the app on the Dokku host
$ sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git # Install Postgres for Dokku
$ dokku postgres:create my-rails-app-production # Create a Postgres service with the name `my-rails-app-production`
$ dokku postgres:link my-rails-app-production my-rails-app # Link the Postgres service to your app
The above steps are also explained here.
3. Use your own domain
Most likely you don’t want to use the IP address provided by Digital Ocean to connect to your app in the browser. If you have a domain you can configure it quite quickly to work with your app.
1.) Point the nameservers of your domain to Digital Ocean. Digital Ocean has tutorials for this with different name registrars
2.) Assign the domain to your app in Digital Ocean. In Digital Ocean’s dashboard go to Networking -> Domains to assign the domain to your project
You might also want to set up CNAME and A Records. CNAME records are aliases that map one hostname to another hostname. E.g. www.your-domain.com should map to your-domain.com. An A record tells a request where your domain should direct to, i.e. to which IP
3.) Finally you want to configure Dokku for this domain. This can be done with one simple command from your Dokku box:
$ dokku domains:set my-rails-app my-domain.com
For more domain configuration details the Dokku docs also have a domain section. Keep in mind that changes to DNS can take up to 48h. In my experience it’s usually more like 2 hours before the domain points to the IP and is usable.
4. Set up SSL
Also it’s quite simple to set up SSL for your website running on Dokku. For this we use Let’s Encrypt, but it should also work with Cloudflare for example.
1.) Install and configure Let’s Encrypt for Dokku
$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
$ dokku config:set --no-restart my-rails-app DOKKU_LETSENCRYPT_EMAIL=[email protected]
$ dokku letsencrypt my-rails-app
2.) Set up auto renewal of the certificate via a Cronjob
$ dokku letsencrypt:auto-renew my-rails-app
$ dokku letsencrypt:cron-job --add my-rails-app
That’s it and it was incredibly fast, simple and free thanks to Let’s Encrypt.
5. Deploy
Finally deploy your app to Dokku which is similar to a deploy on Heroku.
Now locally from the directory of your my-rails-app
you can add the Dokku instance as a git remote and deploy:
$ git remote add dokku [email protected]:my-rails-app # replace dokku.me with your domain or IP
$ git push dokku master
Observations
I have tried Dokku over the weekend and really like this as an alternative to the more costly Heroku. It is easy and fast to deploy your app without much dev ops expertise required. The Dokku documentation struck me as very good and has sections for the areas I was interested in, like SSL configuration and environment variables. The limitation is that Dokku only supports one server, so while it’s good for side projects it is currently not the right tool for a huge infrastructure.
Dokku commands
dokku logs -t // application logs
dokku nginx:access-logs -t // NGINX logs
dokku ps:restart // restart the app
dokku run app_name rails c // access application Rails console
dokku postgres:connect my-rails-app-pg // access PostgreSQL console
dokku config:set app_name ENV=prod COMPILE_ASSETS=1 // set env variables
dokku run app_name rake db:migrate // run migrations