Fire Your DevOps Team: A Solo Dev’s Guide to Kamal 2
Source: Dev.to
The Deployment Dilemma
For the last decade, developers have been stuck between a rock and a hard place.
- The PaaS Trap (Heroku, Render, Fly): extremely easy to use, but the moment you need more than 512 MB of RAM, the price jumps from $7 to $50 to $200. You pay a “convenience tax.”
- The Cloud Maze (AWS, Kubernetes): infinite power and cheaper raw resources, but you need a PhD in IAM roles, VPCs, and load balancers to serve a “Hello World” app.
Enter Kamal.
Created by Basecamp (the makers of Rails), Kamal bridges this gap. It gives you the ownership and low cost of raw VPS hardware, with the ease of a git push‑style deployment.
With the release of Kamal 2, it is finally ready for the masses. Here is how I deployed a production‑ready app to a $5 Hetzner server in under 10 minutes.
What is Kamal?
Kamal is essentially “Capistrano for containers.” It runs locally on your laptop. When you type kamal deploy, it:
- Builds your Docker image locally (or on a builder).
- Pushes it to a registry (Docker Hub, GitHub Packages, etc.).
- SSHs into your server(s).
- Pulls the new image.
- Boots it up alongside the old version.
- Switches traffic over (blue/green deployment) using its built‑in proxy.
- Kills the old version.
There is no “master node” and no Kubernetes cluster state to manage. If you lose your laptop, your server keeps running.
The Hardware: The $5 Powerhouse
Go to Hetzner (or DigitalOcean/Linode) and buy a cheap VPS. For roughly $5 / month you can get an ARM server with 2 vCPUs and 4 GB of RAM.
On Heroku, a “Performance” dyno with similar specs would cost $250 +/ month. That math makes Kamal a no‑brainer for solo developers.
The Guide: From Zero to SSL
1. Installation
Assuming you have Docker running locally:
gem install kamal
kamal init
2. Configuration (config/deploy.yml)
Kamal 2 simplified configuration massively. Here is all you need:
service: my-app
image: your-username/my-app
servers:
web:
- 123.45.67.89 # Your VPS IP address
# The registry where your Docker images live
registry:
server: ghcr.io
username: your-username
password:
- KAMAL_REGISTRY_PASSWORD
# Inject environment variables
env:
secret:
- RAILS_MASTER_KEY
- POSTGRES_PASSWORD
3. The Magic of Kamal 2: The Proxy
In Kamal 1 you had to configure Traefik manually to handle SSL. Kamal 2 includes kamal-proxy by default, which automatically handles:
- Zero‑downtime deployments: holds requests while your app restarts.
- Auto‑SSL: talks to Let’s Encrypt automatically to give you HTTPS.
Add this to your deploy.yml:
proxy:
ssl: true
host: myapp.com
4. What About the Database?
For a true “one‑person” setup you can run the database on the same $5 server using Accessories. Kamal will boot a Postgres container and manage it for you:
accessories:
db:
image: postgres:15
host: 123.45.67.89
port: 5432
env:
POSTGRES_DB: my_app_production
POSTGRES_USER: my_app
POSTGRES_PASSWORD:
- POSTGRES_PASSWORD
files:
# Persist data to the host disk so it survives restarts!
- db_data:/var/lib/postgresql/data
5. The Launch
Run the single command:
kamal setup
kamal setup will:
- SSH into your VPS and install Docker.
- Start your database accessory.
- Start the Kamal proxy.
- Build your app.
- Start your app.
- Issue an SSL certificate.
In about 3–5 minutes your app is live at https://myapp.com.
Day 2 Operations: Sleep Easy
Deploying a Bug Fix
kamal rollback
Kamal keeps the old containers (stopped). A rollback simply switches the proxy pointer back to the previous container, taking about 10 seconds.
Running a Rails Console
kamal app exec -i 'bin/rails console'
You are instantly dropped into a remote console session on your server.
Summary
The “DevOps guy” used to be a mandatory hire. With Kamal 2, the barrier to owning your own infrastructure has collapsed. You don’t need Kubernetes or AWS Lambda—just a Linux box, an SSH key, and Kamal.
Fire your DevOps team (or rather, stop trying to be one). Get back to coding.