Back to tutorials

Deploy a Rails app to Ubuntu with Dokku in 2022

Foreword: Who should read this?

In this guide, I will introduce how to deploy a Ruby on Rails app from scratch with the Dokku open source program. This guide aims at beginners who are passionate about deploying their Ruby on Rails applications to the Internet.

After you practice with the guide, you should be able to push your Rails app to the Internet with about ~20 lines of easy to understand commands(even for beginners without too much Linux knowledge!). It will give you a working online Rails app without much overhead: a database connected with your app, a domain name guarded with https, a redirect from non-www to www or vice versa. After the initial deployment, the proceeding deployments only take a simple "git push".

Introduction: Four approaches commonly used to deploy a Ruby on Rails web application

I'll briefly talk about the 4 approaches then focus on the 4th approach: deploy with git push Dokku.

Option No.1 is the most straightforward approach, like setting up a Rails develop environment on your local machine, a similar environment should be set up on the server manually by you. The only two differences are:

First, on your local dev machine(your desktop PC or Mac laptop), you generate default Rails scaffold code with rails new and then type your business code through a keyboard. But instead of typing them again on the server, you need to upload the code to your server from your local machine, maybe with a SCP upload GUI or through the command line.

Second, when developing, you run the Rails server with bin/rails server or bin/dev, which serves the HTTP server in development mode. But when deploying your Ruby on Rails app, you need to specify the environment to be production mode.

Option No.2 is similar to option No.1, but saves you some effort in uploading your code, it also manages running your application in stage/production mode for you. In this approach, setting up the rbenv/rvm and Ruby like that in option No.1 is still required. Additionally, the Capistrano software needs to be set up by yourself. I've heard of people running 5 year old profitable Ruby on Rails applications with this approach.

Option No.3 is more of an enterprise selection. Basecamp runs their Hey product with both k8s and Docker. Container based deployment is good when you have a team and a single server is not enough for serving your app. But extra effort needs to be put into maintaining the Docker configurations.

Option No.4 is the main topic of this guide. Heroku is a managed cloud service, Dokku is an open source software which you can install on any of your servers. After installing the Dokku software on your server, you can get a "herokuish" flavored deployment environment: deploy with a single line of "git push".

Obtaining a domain name

If this is your first time to deploy a website, you need to buy a domain name, so that people could find your website with your domain name like www.domain.name (e.g. this site uses www.railsbay.com, Google uses www.google.com).

My favorite domain registrar is Namesilo.

They offer a fair price and free WHOIS privacy without any bragging. If you use RailsBay's special coupon: RAILSBAY100 when checking out on NameSilo(this is an affiliate link), you can get a 1.00 USD discount on your first domain purchase.

Setting up your cloud server

Besides purchasing a domain name, another infrastructure you have to buy is a virtual private server(or cloud server). I used to deploy my apps on Digital Ocean's vps but nowadays I'm also happy with Linode's services.

Note: If you use the links above to register an account, you can get 100 USD credits as a first time user. I can also get some credits if applicable! If you dislike it, here is the link without aff: Digital Ocean. Apart from DO, you can also use AWS ec2 or other cloud servers, as long as they provide a command line interface that you can ssh into, they are all fine.

Linking your domain name to your cloud server

When you're done provisioning a server and purchasing a domain name, don't forget to link them! You need to set an "A Record" in your DNS provider(usually the company where you bought your domain) to point to the public IP address provided by your VPS vendor(Digital Ocean, AWS EC2, Linode for example).

I usually point www.railsbay.com and railsbay.com both to my server IP, e.g.: 198.11.5.256(Don't use this one, use the IP your server possesses!). After doing this, when people input the domain name in the browser address bar, the browser can find the actual server that domain lives in by looking up the DNS servers. Be sure to wait a few hours for the DNS to propagate.

Installing Dokku

To install the Dokku open source software, and set a global domain, run the following three commands in your Ubuntu cloud server.

bash - on your cloud server

$ wget https://raw.githubusercontent.com/dokku/dokku/v0.26.8/bootstrap.sh;
$ sudo DOKKU_TAG=v0.26.8 bash bootstrap.sh
$ dokku domains:set-global 198.11.5.256 # use your server IP address here

If you are not comfortable running some random scripts, you can also refer to Dokku's official website: Getting Started with Dokku to install Dokku.

Installing a Dokku database plugin

To install a PostgreSQL or MySQL plugin, managed by Dokku on your server (take PostgreSQL for example):

bash - on your cloud server

$ sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git

Installing a Dokku Redis plugin

To install a redis plugin, managed by Dokku on your server:

bash - on your cloud server

$ sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis

Creating your first Dokku based Ruby on Rails application

Now that our infrastructure is ready, we may proceed to push our Rails app to the cloud server. First we need to create a Dokku app, then we'll create a corresponding database for this app, finally we'll connect the database to the app.

bash - on your cloud server

$ dokku apps:create sample-app
$ dokku postgres:create sample-app-db
$ dokku postgres:link sample-app-db sample-app
$ dokku redis:create sample-app-redis
$ dokku redis:link sample-app-redis sample-app

A Dokku app container named "sample-app" is created, but no code is inside. We then need to push our Rails app's code from our local machine.

bash - on your local machine

$ git remote add dokku dokku@198.11.5.256:sample-app
$ git push dokku main

You can then find from the terminal that your Rails app is already running. You should be able to visit the app with your "IP:port", where the port is generated by Dokku automatically, such as: http://198.11.5.256:54930, you can find this address from the terminal output after running the git command, if your app deployed successfully.

And don't forget to migrate the database if you haven't:

bash - on your cloud server

$ dokku run sample-app rails db:migrate

Setting up domain name and HTTPS/SSL cert for your Rails app

Now that we can visit our app through an IP address with a port number, but how to visit the app by entering our domain name in the browser? To do this, we need to set a Dokku domain for our app:

bash - on your cloud server

$ dokku domains:set sample-app www.domain.name # use the domain name you bought here
$ dokku domains:set sample-app domain.name # use the domain name you bought here

Then you should be able to visit your Rails app by entering the domain name: http://www.domain.name from the browser! Don't worry if it doesn't work, if you have successfully set the DNS for your app, wait a few minutes or an hour. The DNS record needs a couple of minutes to propagate until people can visit your app by that domain name.

Thanks to Let's Encrypt, setting a SSL cert (HTTPS connection) to your Rails app with Dokku is now super easy. Just use the following scripts and a cert will be issued for your app, and will be automatically updated when it gets near to the date to expire.

bash - on your cloud server

$ sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
$ dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=your-email@www.domain.name
$ dokku letsencrypt:enable sample-app
$ dokku letsencrypt:cron-job --add

Now you should be able to visit your app with HTTPS connection in the browser: https://www.domain.name!

Redirect from non-www(bare domain) to www

Usually we want our users and search engines to stay in a single domain, instead of handling this redirect with Rails, we ask Dokku to set that for us. Dokku will set a redirect within it's Nginx config file, so we don't have to write that ourselves:

bash - on your cloud server

$ dokku plugin:install https://github.com/dokku/dokku-redirect.git
$ dokku redirect:set sample-app domain.name www.domain.name

By default a 301 redirect will be the response.

Further deploys

Congratulations if you've made your way here! Now we're 100% done with deploying your Rails app! If you've made any fantastic changes to your app and want your users to enjoy them right then, only a single line of command is required to push your new release to the Internet:

bash - on your local machine

$ git push dokku main

And you're all set!

Cheers!

Written by printfinn, creator of RailsBay. Last updated on Mar 18, 2022.

Back to tutorials