Guides

Kamal Deployment

Deploy containerized applications using Kamal

Deploy with Kamal

Kamal makes deploying Rails apps to your Cassette simple. It handles Docker containers, zero-downtime deployments, and SSL certificates automatically.

Prerequisites

  • A running Cassette
  • Docker installed locally
  • A Docker Hub account (or other registry)
  • Your app with a Dockerfile

Quick Start

1. Install Kamal

BASH
gem install kamal

2. Initialize in Your Project

BASH
kamal init

3. Configure config/deploy.yml

YAML
service: myapp
image: youruser/myapp

servers:
  web:
    - YOUR_CASSETTE_IP

ssh:
  user: cassette

proxy:
  ssl: true
  host: myapp.com

registry:
  username: youruser
  password:
    - KAMAL_REGISTRY_PASSWORD

env:
  secret:
    - RAILS_MASTER_KEY

4. Set Up Secrets

Create .kamal/secrets:

CODE
KAMAL_REGISTRY_PASSWORD=your-docker-hub-token
RAILS_MASTER_KEY=your-master-key

5. Deploy

BASH
kamal setup    # First time only
kamal deploy   # All subsequent deploys

Common Commands

BASH
# View logs
kamal app logs -f

# Rails console
kamal app exec -i 'bin/rails console'

# Run migrations
kamal app exec 'bin/rails db:migrate'

# Restart the app
kamal app restart

# Rollback to previous version
kamal rollback

Adding a Database

For PostgreSQL, add to config/deploy.yml:

YAML
accessories:
  db:
    image: postgres:16
    host: YOUR_CASSETTE_IP
    port: 5432
    env:
      secret:
        - POSTGRES_PASSWORD
    directories:
      - data:/var/lib/postgresql/data

Then add to .kamal/secrets:

CODE
POSTGRES_PASSWORD=secure-password
DATABASE_URL=postgresql://postgres:secure-password@myapp-db:5432/myapp

Boot the database:

BASH
kamal accessory boot db

SSL Certificates

Kamal 2 handles SSL automatically via kamal-proxy. Just set your domain:

YAML
proxy:
  ssl: true
  host: myapp.com

Point your DNS to your Cassette's IP address and certificates are provisioned on first request.

Troubleshooting

Container won't start:
bash
kamal app logs --lines 100

Can't connect to Cassette:
bash
ssh cassette@YOUR_CASSETTE_IP

Registry auth failed:
bash
kamal registry login

Check what's running:
bash
kamal app details
kamal accessory details all

Tips

  1. Test builds locally first: kamal build before deploying
  2. Watch deploys: kamal app logs -f in another terminal during deploy
  3. Use Cassette Rewind: Create a backup before major changes
  4. Keep secrets out of git: .kamal/secrets should be in .gitignore

For the full Kamal documentation, see kamal-deploy.org.