Dev Tools

Kamal 2 Deploys Anywhere With One Yaml

All articles
🚢📜⚙️

Heroku-style deploys, no Heroku bill, one yaml

Spoiler: Basecamp shipped Kamal 2 and it's the closest thing to "git push heroku main" I've felt since 2014. Do not @ me — I migrated a side project off Netlify Functions for the bin and it actually worked.

The Setup

Kamal is a ruby gem that wraps Docker, Traefik, and SSH into one deploy command. You point it at a VPS, hand it a yaml file, and it does zero-downtime rolling deploys with health checks. On my M4 Mac it takes about two minutes from cold.

# config/deploy.yml
service: astro-site
image: aidxn/astro-site

servers:
  web:
    hosts:
      - 5.161.42.7
    options:
      network: "private"

registry:
  username: aidxn
  password:
    - KAMAL_REGISTRY_PASSWORD

env:
  secret:
    - SUPABASE_SERVICE_ROLE_KEY
    - PIPEDRIVE_API_TOKEN

proxy:
  ssl: true
  host: deploy.aidxn.com

The Money Pattern

One command, zero downtime, real SSL. The new kamal-proxy replaces Traefik for most cases and the health-check window is configurable per service. Behold:

kamal setup           # first-run bootstrap
kamal deploy          # build, push, swap

# rollback if something explodes
kamal rollback v42

# tail logs across all hosts
kamal app logs --follow

The Catch

It feels imperative. There's no built-in observability — no metrics, no tracing, no dashboard. You bring your own Grafana or you live in tail-logs land. And it's still ruby-first, so if your team can't read a Gemfile you'll trip on edge cases.

The Verdict

For solo-dev VPS deploys and small teams, Kamal 2 is the new default. Pair it with a $6 Hetzner box and a Supabase backend and you've got a Heroku-tier DX for the price of a coffee. Multi-tenant SaaS still wants Netlify or Fly for the niceties, but for everything else Kamal earned the slot.

Let us make some quick suggestions?
Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.