Deploying Rails 8 with Kamal: Replicating the Heroku Git Push Experience
Deploying a Rails application has traditionally been a complex process, but with the introduction of Kamal in Rails 8.1, it’s now possible to achieve a deployment workflow as simple as Heroku’s git push. Kamal, previously known as MRSK,2 is a deployment tool integrated into Rails 8 that allows developers to deploy applications to any server with minimal configuration. This article walks through setting up Kamal for a Rails 8 app, creating a streamlined deployment process that mirrors Heroku’s ease of use.
What is Kamal?
Kamal is a lightweight deployment tool designed to work seamlessly with Rails applications. It uses Docker under the hood to containerize your app, making deployments consistent and predictable across different environments. Unlike Heroku, which manages infrastructure for you, Kamal gives you full control over your servers while maintaining a simple deployment interface. With Rails 8, Kamal comes built-in, ready to use with a few configuration steps.3
Why Replicate Heroku’s Git Push Experience?
Heroku revolutionized deployment for developers by making it as easy as pushing code to a Git repository. With a single git push heroku main, your app is built, deployed, and running. While Kamal requires a bit more setup initially, we can replicate this simplicity by automating the deployment process using Git hooks or GitHub Actions, allowing a git push to trigger a deployment.
Prerequisites
Before diving into the setup, ensure you have the following:
- A Rails 8 application
- Docker installed on your development machine and server
- A server with SSH access where the app will be deployed
- A Git repository for your project
Step 1:Initialize Kamal in Your Rails 8 App
Rails 8 includes Kamal by default, so there’s no need to install it separately. To initialize Kamal, run the following command in your Rails app directory:3\n\n```bash\nbin/rails kamal:setup
This generates a `config/deploy.yml` file, which is the heart of Kamal’s configuration. Open this file and customize it to match your server setup. A basic configuration might look like this:
```yaml
# config/deploy.yml
service: my-rails-app
image: username/my-rails-app
servers:
web:
hosts:
- 192.168.1.100
labels:
traefik.http.routers.web.rule: Host(`myapp.com`)
registry:
username: username
password:
- KAMAL_REGISTRY_PASSWORD
service: The name of your application.image: The Docker image name that will be built and pushed to a registry.servers.web.hosts: The IP address or domain of your deployment server.registry: Credentials for your Docker registry (e.g., Docker Hub).
You’ll also need to set the KAMAL_REGISTRY_PASSWORD environment variable on your server or in your CI/CD pipeline.
Step 2:Prepare Your Server
Kamal assumes your server has Docker installed and is accessible via SSH. To prepare your server, log in and install Docker if it’s not already present:
sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
Ensure your SSH key is set up for passwordless access to the server, as Kamal uses SSH to execute commands remotely.
Step 3:Deploying with Kamal
Once your configuration is ready, deploy your application with:
bin/rails kamal:deploy
Kamal will build a Docker image of your Rails app, push it to the specified registry, pull it onto your server, and start the containers.4 If everything is configured correctly, your app should be live on the server.
Step 4:Automating Deployment on Git Push
To replicate Heroku’s git push experience, we can use a GitHub Action to trigger a deployment whenever code is pushed to the main branch. Create a workflow file in .github/workflows/deploy.yml:
name: Deploy with Kamal
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
- name: Install dependencies
run: bundle install
- name: Deploy to server
env:
KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
run: bin/rails kamal:deploy
Store your registry password as a GitHub Secret named KAMAL_REGISTRY_PASSWORD. With this setup, every push to the main branch will trigger a deployment, closely mimicking Heroku’s workflow.5\n\n## Step 5: Handling Database Migrations
Just like Heroku, you may need to run database migrations after deployment. Kamal provides a way to execute commands on the server. After a successful deployment, run:6\n\n```bash\nbin/rails kamal:app:exec — rake db:migrate
You can also add this step to your GitHub Action if you want migrations to run automatically:
```yaml
- name: Run migrations
env:
KAMAL_REGISTRY_PASSWORD: ${{ secrets.KAMAL_REGISTRY_PASSWORD }}
run: bin/rails kamal:app:exec -- rake db:migrate
Troubleshooting Common Issues
- SSH Connection Problems: Ensure your SSH key is correctly configured and accessible by Kamal. Test with
ssh -v user@serverto debug connection issues. - Docker Registry Errors: Double-check your registry credentials in
config/deploy.ymland ensure theKAMAL_REGISTRY_PASSWORDenvironment variable is set. - Container Startup Failures: View logs with
bin/rails kamal:app:logsto diagnose issues with your app starting on the server.
Conclusion
With Kamal in Rails 8, deploying a Rails application is simpler than ever. By setting up a GitHub Action, you can replicate the Heroku git push experience, automating deployments with minimal effort. Kamal offers the flexibility of managing your own servers while maintaining an approachable deployment workflow, making it an excellent choice for Rails developers looking to move beyond Heroku or traditional deployment methods.
If you have any questions or run into issues, feel free to reach out for assistance. Happy deploying!
Footnotes
-
Ruby on Rails Guides, “8.0 Release Notes,” accessed March 23, 2026, https://guides.rubyonrails.org/8_0_release_notes.html. ↩
-
Basecamp, “kamal,” GitHub repository, accessed March 23, 2026, https://github.com/basecamp/kamal. ↩
-
Kamal Documentation, “Kamal — Deploy web apps anywhere,” accessed March 23, 2026, https://kamal-deploy.org. ↩ ↩2
-
Kamal Documentation, “kamal deploy,” https://kamal-deploy.org/docs/commands/deploy/, accessed March 23, 2026. ↩
-
GitHub, “Building and testing Ruby,” GitHub Actions Documentation, accessed March 23, 2026, https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-ruby. ↩
-
Kamal Documentation, “kamal app,” https://kamal-deploy.org/docs/commands/app/, accessed March 23, 2026. ↩
You May Also Like
Time to Migrate from Heroku: Evaluating Render, Fly.io, and Railway for Rails
An engineering leader's guide to the Heroku platform transition, comparing Render, Fly.io, and Railway as modern PaaS alternatives for Ruby on Rails applications.
Transitioning a Monolithic Rails App to Docker and AWS ECS/Fargate
A comprehensive guide for engineering leaders on containerizing large and complex Ruby on Rails applications using Docker and AWS ECS/Fargate.
Rails Transition: From RAILS_ENV to Rails.env and Environment Predicates
Learn how Rails evolved from using the RAILS_ENV constant to Rails.env with convenient predicate methods, and how to modernize your legacy codebase.