ScriptsApr 15, 2026·3 min read

Kamal — Zero-Downtime Docker Deploys to Any Server

Kamal is Basecamp's deploy tool that ships Docker containers to bare metal or cloud VMs with a single command, giving you Heroku-like workflows on servers you actually own.

Introduction

Kamal (originally MRSK) is a deployment tool from 37signals/Basecamp that turns any Linux box with SSH access into a target for zero-downtime Docker deploys. It was written to escape their multi-million-dollar cloud bill — and to prove that modern ops can be simple again. v2 added kamal-proxy, a purpose-built Go reverse proxy replacing Traefik, with first-class support for blue/green, canary, and TLS via Let's Encrypt. Over 14,000 GitHub stars.

What Kamal Does

  • Builds your container image and pushes to any OCI registry (Docker Hub, GHCR, ECR, self-hosted).
  • SSHes into each server, pulls the new image, boots containers, and drains the old ones behind kamal-proxy.
  • Manages secrets via .env encrypted with 1Password, Doppler, Bitwarden, or age.
  • Coordinates multi-role deployments — web, workers, cron, accessories (Postgres, Redis, etc.).
  • Provides a single CLI for deploy, rollback, logs, exec, console, db, prune.

Architecture Overview

Kamal is a Ruby gem that orchestrates over SSH (via net-ssh) and speaks to the Docker daemon on each host. There's no agent on the servers — just Docker + kamal-proxy. A deploy does: docker build locally (or with BuildKit), push to registry, ssh to each server in parallel, pull, boot, health-check, then kamal-proxy deploy to swap traffic with connection draining. Accessories (Postgres, Redis, Clickhouse) are first-class services with their own lifecycle. Secrets are encrypted at rest and injected as env vars at boot.

Self-Hosting & Configuration

  • Install the kamal gem on your workstation; servers only need SSH + Docker (kamal setup installs both).
  • Define everything in config/deploy.yml: hosts, image, roles, env, proxy rules, accessories.
  • Put secrets in .kamal/secrets and reference them via KAMAL_VAR; use 1Password/Doppler/Bitwarden shims for prod.
  • Enable SSL: set proxy.ssl: true and Kamal-proxy auto-provisions Let's Encrypt certs.
  • Use mirror registry mode to avoid pulling the same image on every host.

Key Features

  • Zero-downtime deploys with health-check gating and connection draining.
  • Multi-server, multi-role topologies managed from a single YAML file.
  • Blue/green, canary, and rolling deploys via kamal-proxy.
  • No control plane — if your SSH works, your deploys work.
  • Written by the Rails/Basecamp team, dogfooded on ONCE, Hey, and Basecamp.

Comparison with Similar Tools

  • Dokku — self-hosted Heroku with buildpacks; Kamal skips buildpacks and uses your own Dockerfile.
  • CapRover / Coolify — PaaS with a web UI; Kamal is CLI-first and thinner.
  • Capistrano — classic Ruby SSH deploy; Kamal replaces it for containerized apps.
  • Fly Machines / Render — managed serverless; Kamal is for teams who want their own servers.
  • Kubernetes — scales bigger but needs a full team to run; Kamal fits 1-50 servers.

FAQ

Q: Do I need a load balancer in front? A: No — kamal-proxy handles TLS termination and traffic routing on the hosts themselves.

Q: Can I deploy non-Ruby apps? A: Yes. Kamal only cares about Docker images; the app inside can be anything.

Q: How does secret management work in CI? A: Set KAMAL_REGISTRY_PASSWORD + app secrets as CI variables; Kamal picks them up through the adapter you configure.

Q: Does Kamal support Kubernetes? A: No — it's deliberately K8s-free. If you want Kubernetes, use Helm or ArgoCD.

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets