Software & Apps

Deploying Rails in Docker: Kamal alternative


Back to the blog

Deploying Rails in Docker: Kamal alternative

Paweł Dąbrowski

Founder / Software Engineer

Recently, Basecamp, the creators of Ruby on Rails, released a solution for deploying it on bare metal servers. Kamal is Capistrano for Containers and an alternative solution to Capistrano, Kubernetes, and Docker Swarm.

If you want to deploy your Rails application on a bare metal server but don’t like how Kamal works, there is a good and more straightforward alternative: Dokku. It’s Heroku, but for your own server.

I have used Dokku for years, and it works perfectly. With support for Sidekiq, ElasticSearch, and other application components, you can prepare a production environment for Rails in minutes. In this article, I will guide you through preparing the server environment and deploying the Rails application. As a bonus, I will show you a tool called No deployment which automates the entire setup for your production and stage environments.

dash

The first step is to download and run the Dokku installation script on the server. The solution can be installed on the latest Ubuntu and Debian 11+ distributions.

SSH to your server, download the installation script, and run it:

wget -NP . https://dokku.com/install/v0.35.12/bootstrap.sh

sudo DOKKU_TAG=v0.35.12 bash bootstrap.sh

The installation should take about 5 minutes to complete. Once this is done, the next step is to add an SSH key so that you can deploy your application using GIT as is possible with Heroku:

echo "public ssh key" | sudo dokku ssh-keys:add admin

Similarly, you can add subsequent users who can deploy the application. To add access to the server, edit ~/.ssh/authorized_keys and paste the SSH key of the person you want to authenticate.

Create a new application

Creating a new application is straightforward. All you need to do is call the create command:

dokku apps:create myrailsapp

If you push the application now, Dokku will recognize that you are pushing a Rails application and install the specific version of Ruby. However, we cannot do this now because we have not yet defined the correct environment variables.

Let’s start by building a sample Rails application with support for PostgreSQL as a database engine:

rails _8.0.1_ new myrailsapp --skip-kamal —skip-docker --skip-solid --skip-thurster --skip-devcontainer --database=postgresql

We can now go back to the server and take care of the database.

High-Performance Active Record

Master the art of database optimization in Rails applications. Learn proven methods to improve your Ruby on Rails application performance.

Database configuration

We have done the base configuration of Dokku. Regarding additional components for our application, Dokku uses plugins to manage them easily. The first step is to install the PostgreSQL plugin:

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

The next step is to create the database itself. Since we are operating in containers, we need to make the database available for our app containers. This process is called linking.

Let’s create the database:

dokku postgres:create myrailsapp-db

Then, let’s link the database container to the application:

dokku postgres:link myrailsapp-db myrailsapp

Thanks to this operation, Dokku automatically configures the DATABASE_URL environment variable that contains the connection string for our application. Regarding the environment variables, let’s add the base variables for the application today.

Environment variables

A Basic Rails application, requires some basic environment variables to function properly. For example, the SECRET_KEY_BASE value is used to generate different security keys for the environment. You can generate the desired amount by running the rails secretly and then copying the amount.

Apart from the mentioned environment variable, we will also add some others to make sure we run the app in production mode:

dokku config:set myrailsapp SECRET_KEY_BASE=mysecret RAILS_ENV=production RACK_ENV=production RAILS_LOG_TO_STDOUT=enabled RAILS_SERVE_STATIC_FILES=enabled

When you add environment variables, Dokku will handle updating the application, so you don’t have to worry about it. Since we haven’t pushed the application’s source code yet, the process only takes a second.

Domain and SSL configuration

The easiest way to configure the domain using the Dokku application is to define an A record in the DNS settings that points to the server IP address. I will do this now, using the myrailsapp.impactahead.com subdomain for the purpose of this article.

I use Cloudflare, but the process is the same for most DNS providers. Copy the server’s IP address, select A record, set the subdomain (or leave the subdomain field empty if you want to use the domain), and paste the IP record. If you’re also using Cloudflare, turn off the proxy setting.

Return to the server; the next step is to clear the default domain values ​​and add the domain:

dokku domains:clear-global
dokku domains:clear myrailsapp
dokku domains:add myrailsapp myrailsapp.impactahead.com

The process of configuring SSL certificates is also very simple. Dokku uses the Lets Encrypt plugin to manage all related processes. Let’s install it:

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

The last step in the configuration is the information about the e-mail where the information about the expiration of the SSL will be sent:

dokku letsencrypt:set myrailsapp email your-email

We can now enable SSL for our application. The plugin will attempt to configure the certificate and update the server configuration. At this stage, the DNS change should be propagated; otherwise, SSL verification will fail. Execute the following command:

dokku letsencrypt:enable myrailsapp

After SSL is created, we are done with server configuration. If you don’t want to renew the SSL certificate manually, you can set up cron to do it automatically:

dokku letsencrypt:cron-job --add

Prepare the rail application for deployment

We need to tell Dokku that we want to use a worker to run our web server. To do this, create Procfile file in the main directory with the following lines:

web: bundle exec rails server -p $PORT -e $RAILS_ENV
release: bundle exec rails db:migrate

Update Gemfile with your Ruby version declaration and run the bundle install:

The last step is to add GIT remote so we can deploy our application in Heroku way:

git remote add dokku dokku@ip-address:myrailsapp

We can now push our application:

git add .
git commit -m "Hello world"
git push dokku main

Dokku does not require a Dockerfile to properly install dependencies for a Rails app; the specific version of Ruby is sufficient. After the deployment is complete, you can visit the configured domain, but you will see a 404 error. We could not determine the root page. You can do something simple HomeController with an index action that will translate “Hello world” and make it the root page. Deploy the app again, and you should see the welcome screen.

Master the art of database optimization in Rails applications. Learn proven methods to improve your Ruby on Rails application performance.

Bonus: deployment automation without deployment

Basically, deploying a Rails application to Dokku requires the same steps. To speed up the deployment configuration, I did the Unused gemwhich makes it effortless. While your Dokku configuration is being prepared, you can make yourself a coffee.

Start adding the gem to the development group:

group :development do
  gem "deployless"
end

trends bundle install to install the library. Prepare the IP address of your server and the domain you want to use for the application. Run the interactive setup:

You will need to provide some basic details, such as the server’s IP address, username, path to your SSH key, and application name. When you are done, a .deployless.yml file is created, and the .gitignore The file has been updated to exclude this configuration file from the repository.

You can trigger the deployment configuration for the production environment by using the following command:

The library will connect to the server, install Dokku, and prepare all the components for your application. All you have to do is make sure that a proper DNS record is added to make the domain available for the server – the library will stop the process and ask if this step is ready to finish the domain and configure the SSL.

Once the process is complete, you can add a new GIT remote and push the code to deploy the application. If you check .deployless.yml file, you will also notice the environment variables. Once you update it, you can force the change on the server by running:

dpls production update-env

Connecting to the production Rails console is also as effortless as executing the following command:


https://impactahead.com/assets/impactahead-94da600f.jpg

2025-01-21 20:32:00

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button