Deploy a Rails app to Ubuntu with Dokku in 2023
by printfinn, Last updated on Mar 18, 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
- Set up rbenv/rvm, Ruby and Rails then upload code manually.
- Set up rbenv/rvm, Ruby and Rails then deploy with Capistrano.
- Container based approaches: Docker and k8s.
- Git push to Heroku / Git push with Dokku.
- With the MRSK Gem
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.
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. 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.: 18.104.22.1686(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.
To install the Dokku open source software, and set a global domain, run the following three commands in your Ubuntu cloud server.
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):
Installing a Dokku Redis plugin
To install a redis plugin, managed by Dokku on your server:
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.
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.
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://22.214.171.1246: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:
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:
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.
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:
By default a 301 redirect will be the response.
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:
And you're all set!