Getting started with Kamal for containerized deployments
Kamal provides a Docker-based alternative to Capistrano for deploying web applications to Linux servers with zero downtime. Using Kamal 2 and Kamal Proxy, teams can manage SSL via Let's Encrypt and run multiple applications on bare metal or cloud VMs like Hetzner.
Moving from Capistrano to Docker
Kamal uses Docker to deploy web applications to any Linux server with zero downtime. It works on bare metal or cloud VMs like Hetzner or Digital Ocean. This tool provides a way to escape the costs of managed platforms like Heroku or Fly.io. One can use a list of IP addresses for vanilla Ubuntu servers to run applications in minutes. Kamal provides the procedural simplicity of Capistrano but uses modern containerization. It is an imperative tool that provides the procedural simplicity of Capistrano while using modern containerization to ensure that your production applications run reliably on any Linux server you provide. It is possible to run multiple applications on a single server. One can feed the config file a list of IP addresses for Ubuntu servers that have only had an SSH key added. This approach gives portability between different cloud providers. One can deploy to several clouds with ease.
Configuration and Kamal 2
Rails 8 includes Kamal 2 with default configurations for the gem, deploy file, and secrets. Kamal 2 replaced Traefik with Kamal Proxy to manage traffic. This proxy handles automatic SSL certificates via Let’s Encrypt and supports multiple applications on one server. Developers can manage sensitive data using the .kamal/secrets file instead of using .env files. The service name is prepended to container names. If the service is demo-app, the Redis accessory will have the name demo-app-redis. This makes it easy to set the REDIS_URL environment variable for Sidekiq to pick up. To install Kamal globally, a Ruby environment is required. Inside the app directory, one runs kamal init.
| Component | Function |
|---|---|
| Kamal Proxy | Routes traffic and manages SSL |
| Accessories | Runs services like Redis or Postgres |
| Docker | Container engine for images |
| SSH | Executes commands on remote hosts |
The tool requires a Linux server, such as Ubuntu 24.04, with at least 2GB of RAM. A domain name and a Docker registry like Docker Hub or Amazon ECR are required. If using Docker Hub, the registry username and password must be added to the configuration. One can also use Amazon ECR if an AWS account and the AWS CLI are available. To use Amazon ECR, an IAM user with AmazonEC2ContainerRegistryFullAccess permissions must be created.
Deployment workflows and limits
The deployment process begins with the kamal setup command. This command installs Docker on target servers, boots the proxy, and deploys the application. For regular updates, one runs kamal deploy to rebuild images and switch traffic to new containers. Kamal keeps old containers on the server to allow for quick rollbacks. If a deployment fails, one can use kamal rollback to switch traffic back to the previous version. However, Kamal records nothing about who deployed what or when, which means the audit trail is limited to version control history. The tool builds the Docker image on whichever machine runs the command, which might be a developer laptop or a CI runner. Developers can use kamal app exec to run commands on the server. One can also use kamal accessory exec to run commands in a specific container like a database. How do you manage deployment queues when multiple engineers attempt to deploy at the same time? You should know that two engineers running kamal deploy at the same time can cause race conditions in your deployment. Developers can use kamal audit to see who deployed what and when if they use the right versions.