kamal-deployment

Kamal is a deployment tool by 37signals that deploys containerized applications to any Linux server using Docker, SSH, and Kamal Proxy. It offers zero-downtime deploys, rolling restarts, automatic SSL/TLS certificates, and auxiliary services management.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "kamal-deployment" with this command: npx skills add faqndo97/ai-skills/faqndo97-ai-skills-kamal-deployment

Kamal 2 Deployment

Kamal is a deployment tool by 37signals that deploys containerized applications to any Linux server using Docker, SSH, and Kamal Proxy. It offers zero-downtime deploys, rolling restarts, automatic SSL/TLS certificates, and auxiliary services management.

Quick Start

Install

gem install kamal

Initialize in your project

kamal init

Creates: config/deploy.yml, .kamal/secrets, .kamal/hooks/

First deploy (bootstraps servers + deploys)

kamal setup

Subsequent deploys

kamal deploy

Key Concepts

  • Service: Your application name, used to uniquely configure containers

  • Server: A virtual or physical host running your application image

  • Role: A server group running the same command (e.g., web , job )

  • Accessory: A long-running auxiliary service (database, Redis) with independent lifecycle

  • Kamal Proxy: Reverse proxy for zero-downtime deploys and SSL termination on each server

  • Kamal 2 provides its own private network called kamal

  • do NOT add a custom private network in your config

Configuration Reference

For complete deploy.yml configuration, see configuration.md.

Workflows

Initial Setup

  • Run kamal init to generate config files

  • Configure config/deploy.yml (see configuration.md)

  • Set up .kamal/secrets with registry credentials and app secrets

  • Ensure your app has a Dockerfile exposing port 80 with a /up health check

  • Set config.assume_ssl = true and config.force_ssl = true in production.rb

  • Exclude /up from host authorization in Rails 7+: config.host_authorization = { exclude: ->(request) { request.path == "/up" } }

  • Run kamal setup for the first deployment

Deploying Updates

kamal deploy # Full deploy (build + push + deploy) kamal deploy --skip-push # Deploy existing image from registry kamal deploy --version=VERSION # Deploy specific version

Managing Accessories

kamal accessory boot all # Boot all accessories kamal accessory boot postgres # Boot specific accessory kamal accessory reboot redis # Reboot an accessory kamal accessory remove postgres # Remove an accessory kamal accessory details postgres kamal accessory logs postgres

Maintenance & Debugging

Logs

kamal app logs # Application logs kamal app logs -f # Follow logs kamal app logs -r web # Logs for specific role kamal proxy logs # Proxy logs

Console access

kamal app exec -i 'bin/rails console' kamal app exec -i --reuse bash # Shell into running container kamal app exec --primary "bin/rails about"

Rollback

kamal app containers # List available versions kamal rollback [VERSION] # Rollback to version

Redeploy (skip bootstrap, proxy setup, pruning, registry login)

kamal redeploy

Locks

kamal lock status # Check deploy lock kamal lock acquire -m "reason" # Prevent deploys kamal lock release # Allow deploys again

Server management

kamal server bootstrap # Bootstrap servers with Docker kamal details # Show details about all containers kamal audit # Show audit log from servers kamal prune # Prune old images and containers kamal config # Show combined config (includes secrets!) kamal docs [SECTION] # Show Kamal configuration docs

Cleanup

kamal remove # Remove everything from servers

Global Flags

Flag Description

-v, --verbose

Detailed logging

-q, --quiet

Minimal logging

--version=VERSION

Run against specific app version

-p, --primary

Primary host only

-h, --hosts=HOSTS

Comma-separated hosts (supports wildcards)

-r, --roles=ROLES

Comma-separated roles (supports wildcards)

-d, --destination

Deployment destination

-H, --skip-hooks

Skip hook execution

Database Operations

Run migrations via entrypoint (recommended)

bin/docker-entrypoint handles db:prepare automatically

Or via pre-deploy hook

kamal app exec -p -q -d $KAMAL_DESTINATION --version $KAMAL_VERSION "rails db:migrate"

Database backup (with S3 backup accessory)

kamal accessory exec s3_backup "sh backup.sh" kamal accessory exec s3_backup "sh restore.sh"

Architecture Patterns

For complete examples of single-server and multi-server setups, see examples.md.

Single Server (Rails + PostgreSQL + Redis + Sidekiq)

All services on one VPS with Let's Encrypt SSL. Best for small-to-medium apps.

Multi-Server (Scaled)

Separate servers for web, job, database, and cache behind a load balancer on a private network. Best for high-traffic apps.

Hooks

Custom scripts in .kamal/hooks/ that run at deployment points. If a hook returns non-zero, the command aborts.

Available: docker-setup , pre-connect , pre-build , pre-deploy , post-deploy , pre-app-boot , post-app-boot , pre-proxy-reboot , post-proxy-reboot .

For details, see configuration.md.

Upgrading from Kamal 1

kamal upgrade # In-place upgrade from Kamal 1 to 2 kamal upgrade --rolling # Zero-downtime upgrade kamal downgrade # Reverse if needed

Common Gotchas

  • Kamal 2 creates its own kamal network - remove any custom private network from your config

  • Always set config.assume_ssl = true in production.rb when using SSL

  • Do NOT use your domain name as the VM hostname - it overrides /etc/resolv.conf

  • Docker port exposure bypasses UFW - closing ports in UFW is not enough, Docker rules are higher in iptables

  • Short deploy_timeout causes failures on underpowered servers - increase it if deploys fail

  • Asset bridging must be explicitly configured with asset_path

  • it's not automatic

  • Accessories must be removed before moving to a new destination

  • Kamal 2 doesn't support ERB in config/deploy.yml (unlike Kamal 1)

  • Set config.reload_routes = false in Devise initializer to fix ActionController::RoutingError

  • Enable forward_headers: true in proxy config when behind Cloudflare to preserve real client IPs

CI/CD

For GitHub Actions deployment workflows, see cicd.md.

Backups

For database backup strategies with S3, see backups.md.

Server Hardening

For production server security setup, see server-hardening.md.

Logging & Monitoring

For Vector log aggregation and structured logging, see logging.md.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ruby-llm

No summary provided by upstream source.

Repository SourceNeeds Review
General

ruby-on-rails

No summary provided by upstream source.

Repository SourceNeeds Review
General

stimulus

No summary provided by upstream source.

Repository SourceNeeds Review
General

shadcn-ui

No summary provided by upstream source.

Repository SourceNeeds Review