Deploying Rails 7 to Linode/Akamai with Dokku

November 29, 2023

Want to deploy Rails to Linode/Akamai? This is your guide.

First - Get a Linode Account

Super easy to get an account. They also have Google auth for really simple signup - which I love. The rest is straight forward, their pricing is fantastic. Click here to visit Linode.

One thing to mention is that Akamai acquired Linode back in 2022, but everything still works just the same and the pricing is fantastic.

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.

When you're in the setup, you'll want the most recent LTS (long term support) version of Ubuntu. At this time, it is Ubuntu 22.04 LTS. Then for a region, I recommend selecting a region close to you or the best possible location for your website audience/customers.

You should also set up SSH Keys at this time.

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

$ ssh root@<server ip from linode>

Now, get the latest version of Dokku on your new server instance.

First, the installation script:

$ wget -NP . https://dokku.com/bootstrap.sh

Next, the installer:

$ sudo DOKKU_TAG=v0.32.3 bash bootstrap.sh

Note: this is the latest version of Dokku as of this writing. Definitely visit the Dokku homepage to ensure you install the latest version.

After the install, you'll see a notice to add the 'dokku' user to the ssh admin credentials.

First copy your public RSA key in your terminal:

pbcopy < ~/.ssh/id_rsa.pub

Then jump back to your SSH to the server:

echo 'CONTENTS_OF_ID_RSA_PUB_FILE' | dokku ssh-keys:add admin

Linode Automatically Has a Swapfile, But Others Don't

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.git
# 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 letsencrypt:set myapp email <e-mail>
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.

Before deploy, make sure you commit all of your changes to your main branch.

$ git add .

$ git commit -m "name of commit"

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

# Terminal within your app folder
git push dokku

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

You must be logged in to comment.