Tutorial: Deploy a Rails app using Kamal
Kamal is a deployment tool for containerized Rails applications. Instead of running tasks over SSH like Capistrano, Kamal builds a Docker image of your application, pushes it to a registry, and runs it on your servers inside lightweight containers.
In RubyMine, you can run Kamal commands directly from the built-in terminal or by using . This makes it easy to trigger deployments, manage environments, and monitor logs without leaving the IDE.
In this tutorial, we'll show you how to deploy a sample Rails application to a remote server using Kamal. As the application server, Puma will run inside a Docker container, with Kamal Proxy handling HTTP and HTTPS traffic.
Prerequisites
To deploy a Rails application with Kamal entirely from RubyMine, make sure your local environment and the remote server meet these requirements.
Local machine
Mac with macOS
RubyMine installed and configured for your Rails project
A Rails 8 application. For older Rails versions, add Kamal to your Gemfile or install it locally with
gem install kamalA valid
Dockerfilein the project rootDocker installed locally
Access to a container registry (Docker Hub, GitHub Container Registry, or private registry) with credentials stored securely
SSH configured locally
Web server
Linux-based host
SSH access for the same user defined in your Kamal
deploy.yml(or in your OpenSSH config)Docker installed and running (Kamal can install it during
kamal setupon fresh hosts)
Deployment
This part of the tutorial describes the steps required to deploy an app with Kamal.
Initialize Kamal
In RubyMine, open the terminal: . Alternatively, click the Terminal icon on the toolbar in the lower left corner of the IDE.
Run the following command:
kamal initThis creates a config/deploy.yml file. This file contains many configuration keys and options for deployment, but in this tutorial, we will focus only on the settings that are necessary for our deployment.
Configure your deployment
Edit the created config/deploy.yml file generated by kamal init.
Below is an example of the file contents:
Manage secrets
In production, Rails requires a valid SECRET_KEY_BASE for encryption and secure operations. Perform the steps below to configure it correctly:
Run one of the following commands to generate a strong
SECRET_KEY_BASE:bin/rails secret # or ruby -rsecurerandom -e 'puts SecureRandom.hex(64)' # or, if using your built Docker image: docker run --rm <your-image> ./bin/rails secretUpdate your config/deploy.yml file by adding the generated key to your environment configuration:
env: clear: RAILS_ENV: production PORT: "3000" SECRET_KEY_BASE: <%= ENV.fetch("SECRET_KEY_BASE") %>Before running the
kamal deploycommand, export the key to your environment:export SECRET_KEY_BASE="<your-generated-value>"
Once deployed, your application will use the provided SECRET_KEY_BASE value for securing sensitive operations.
Run the first-time server setup
Run the kamal setup command to prepare the server for deployment.
Deploy your application
Now that you configured your deployment and made sure the wev server is ready, you can deploy the application.
Run the following command from the RubyMine terminal.
kamal deployKamal will do the following:
Build the Docker image locally
Push it to your registry
Establish an SSH connection to the server
Pull the new image
Launch the application in the configured environment
Once the deployment is complete, open your browser and visit the URL you configured for your application.
Troubleshooting
SSH keeps asking for a passphrase/password
Load your SSH key into the agent to avoid passphrase prompts:
ssh-add ~/.ssh/id_ed25519Add your SSH key to the macOS Keychain for persistent access:
ssh-add --apple-use-keychain -K ~/.ssh/id_ed25519Ensure SSH uses the correct key by configuring ~/.ssh/config:
Host your-server-ip User your-username IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yesTest the SSH connection to verify everything works:
ssh your-username@your-server-ip
Your page returns 404
Check whether requests reach Rails:
# in one shell kamal app logs -f # in another shell curl -I http://app.example.com/If logs are empty, fix the DNS or proxy. If Rails logs show a 404, add a root route in your app.
Check the proxy is routing and healthy:
kamal proxy ps kamal proxy logs -f curl -I -H "Host: app.example.com" http://127.0.0.1Use a health check path that returns 200 (for example, /up) in deploy.yml.
Confirm the app listens on the right port (default 3000) and binds
0.0.0.0:curl -I http://127.0.0.1:3000/
Rollback
Roll back the application to a previous version if the current deployment has issues. This can help quickly restore a stable state.
First, list the available containers to identify previous versions:
kamal app containers -qThen, roll back to a previous image by specifying the desired version or the latest stable one:
kamal rollbackAfter the rollback, monitor logs and the app’s health to ensure the previous version is running correctly.