DEV Community

Alex Spinov
Alex Spinov

Posted on

Kamal 2 Has a Free API — Heres How to Deploy Without Kubernetes

Kamal 2 (from the creators of Rails) deploys your app to bare metal servers with zero downtime. No Kubernetes, no cloud lock-in — just SSH and Docker.

Why Kamal 2?

  • No Kubernetes: Deploy to any server with SSH
  • Zero downtime: Rolling deploys with health checks
  • Multi-server: Deploy across multiple hosts
  • Built-in proxy: Kamal Proxy replaces Traefik
  • Secrets management: Env vars from 1Password, Bitwarden, LastPass
  • Accessories: Deploy Redis, PostgreSQL alongside your app
  • Free: Open source from 37signals

Install

gem install kamal
kamal init
Enter fullscreen mode Exit fullscreen mode

Configuration

# config/deploy.yml
service: my-app
image: my-app

servers:
  web:
    hosts:
      - 192.168.1.1
      - 192.168.1.2
    labels:
      traefik.http.routers.my-app.rule: Host(`app.example.com`)
  worker:
    hosts:
      - 192.168.1.3
    cmd: bundle exec sidekiq

registry:
  username: my-user
  password:
    - KAMAL_REGISTRY_PASSWORD

env:
  clear:
    RAILS_ENV: production
  secret:
    - DATABASE_URL
    - REDIS_URL
    - SECRET_KEY_BASE

accessories:
  db:
    image: postgres:16
    host: 192.168.1.3
    port: 5432
    env:
      clear:
        POSTGRES_DB: my_app_production
      secret:
        - POSTGRES_PASSWORD
    volumes:
      - /var/lib/postgresql/data:/var/lib/postgresql/data
  redis:
    image: redis:7
    host: 192.168.1.3
    port: 6379
Enter fullscreen mode Exit fullscreen mode

Deploy

# First deploy (setup server)
kamal setup

# Subsequent deploys
kamal deploy

# Deploy with version
kamal deploy --version=v1.2.3
Enter fullscreen mode Exit fullscreen mode

Rolling Deploys

Kamal deploys one server at a time, waits for health check, then moves to the next:

healthcheck:
  path: /health
  port: 3000
  interval: 1
  max_attempts: 30
Enter fullscreen mode Exit fullscreen mode

Manage Remotely

# Check app status
kamal app details

# View logs
kamal app logs

# Run console
kamal app exec --interactive 'bin/rails console'

# Rollback
kamal rollback v1.1.0
Enter fullscreen mode Exit fullscreen mode

Secrets with 1Password

# .kamal/secrets
SECRET_KEY_BASE=$(op read op://Vault/my-app/SECRET_KEY_BASE)
DATABASE_URL=$(op read op://Vault/my-app/DATABASE_URL)
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

37signals (Basecamp, HEY) uses Kamal to deploy their apps to bare metal. They handle millions of users without Kubernetes. A solo developer deployed their SaaS to two $5 Hetzner VPSes with Kamal — zero downtime deploys, automatic SSL, and $10/mo total hosting.


Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)