August 28, 2022
TAGS: DIGITAL OCEAN | DOKKU | LINODE

Deploying Rails 7 to Linode with Dokku

In this article, I will go through the steps to launch a Rails 7 app using Linode and Dokku. This should be the exact same process for other providers such as Digital Ocean or Vultr (and more not named). I chose Linode because it is super easy to setup an account and the pricing is the best I have seen for the particular server setup I like to run.

First, get a Linode Account

Super easy to get an account. They also have Google auth which I prefer. At the time of this writing, they are offering a $100 credit too. Click here to visit Linode.

Create a Linode

It should go without saying, that Linode calls their server stack instances as Linodes. In the case of Digital Ocean, you would create a Droplet. For my specific case and this tutorial, I am using Linode's Nanode 1 GB plan which is $5 a month.

Point Your Domain Name to the New Server

You will get an ip address once your server is provisioned and running. You will need to create an A record in your DNS entry that points to your server's IP address. See below where I have my A record pointed to my server IP. I also have the CNAME record for "www" pointed to the main domain.

Set up the Server

Open your terminal and SSH into the server

# terminal
$ ssh root@<server ip from linode>

Now, get the latest version of Dokku on the server:

# terminal
# for debian systems, installs Dokku via apt-get
wget https://raw.githubusercontent.com/dokku/dokku/v0.28.1/bootstrap.sh;
sudo DOKKU_TAG=v0.28.1 bash bootstrap.sh

This is the latest version as of the time of this writing. Be sure to check here to see if there is a newer version.

Follow the instructions provided after install to make dokku an admin with rights to your ssh keys.

Set up Swapfile, if needed

Depending on the size of your cloud server, you may want to create a swapfile to handle the deployments better and not run out of resources. When using the smallest droplet on Digital Ocean, I would always use this tactic. With Linode, their smallest instance already has a swapfile attached. In the case you need to make one, follow the instructions below.

# SSH terminal to Linode server
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo sh -c 'echo "/swapfile none swap sw 0 0" >> /etc/fstab'

Add App to Dokku

Be sure to replace myapp with your app name

# SSH terminal to droplet server
dokku apps:create myapp

Add Heroku buildpacks to avoid setting up any dependencies manually.

#SSH terminal to Linode server
dokku buildpacks:add myapp https://github.com/heroku/heroku-buildpack-ruby.git
# Add this if you plan on using Active Storage
dokku buildpacks:add myapp https://github.com/heroku/heroku-buildpack-activestorage-preview
# Add this if you plan on using Node JS
dokku buildpacks:add myapp https://github.com/heroku/heroku-buildpack-nodejs.git

Set up ENV variables on the server:

# SSH terminal to Linode server
dokku config:set myapp RAILS_ENV=production
dokku config:set myapp RAILS_MASTER_KEY=<master_key_from_app>

Your master key will be located in a file called "master.key" in your app's config folder.

Get Postgres up and running:

# SSH terminal to Linode server
dokku plugin:install https://github.com/dokku/dokku-postgres.git
dokku postgres:create myapp_db

Link Postgres DB to app:

# SSH terminal to Linode server
dokku postgres:link myapp_db myapp

Add Procfile to Your App

You need to add a "Procfile" to the root of your app directory. It must be spelled as Procfile with the capitalization on the P. Add the following to your Procfile declarations:

# Procfile
# this tells the app upon deployment to run Puma to serve the app
web: bundle exec puma -C config/puma.rb
# add this line to automatically run migrations upon each deployment
release: bundle exec rails db:migrate

Add Domain(s) and SSL

Now, add domain(s) to your app.

#SSH to Linode server
dokku domains:add myapp example.com
dokku domains:add myapp www.example.com
# If it were subdomain
dokku domains:add myapp myapp.example.com
dokku domains:add myapp www.mayapp.example.com

Acquire SSL Encryption and Certificate.

# SSH to Linode server
dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku config:set --no-restart myapp DOKKU_LETSENCRYPT_EMAIL=[email protected]
dokku letsencrypt:enable myapp
# Add cron job so certificate automatically renews
dokku letsencrypt:cron-job --add myapp

Definitely add the cron job. Let's Encrypt's certificates are only valid for 3 months, so you will want to have the cron job handle getting the new one automatically to keep your domain from experiencing any disruptions.

Deploy Your App

Almost ready to roll. Now, we just need to add a remote repository.

# Terminal within your app folder
git remote add dokku dokku@IP_ADDRESS:myapp

With this setup, it is using the IP Address. If you domain is resolving already and correctly, you could use "myapp.com:myapp" for example. But for now, I will just stick with the IP address.

Deploy app just like you would on Heroku but with Dokku:

# Terminal within your app folder
git push dokku master

Dokku runs one instance of web process by default. You can up that by using this command.

# SSH to Linode server
dokku ps:scale myapp web=2

App Changes and Future Deployments

You should be good to go and if you enabled swap, your experience should be as smooth as using Heroku, just as mine has been.

Going forward, after you commit changes in git inside your app, all you should need to do is to run the "git push dokku master" command and your site will deploy the latest version.


Comments

Sign Up or Login to comment.