Loading...
Loading...
Expert-level Kamal deployment guidance for deploying containerized applications to any server. Use this skill when users ask about Kamal, container deployment, zero-downtime deployments, deploying Rails/web apps to VPS/cloud servers, kamal setup, kamal deploy, Docker deployment without Kubernetes, or deploying to Hetzner/DigitalOcean/AWS with Kamal. Also use when users mention DHH's deployment tool, 37signals deployment, or want an alternative to Heroku/Render/Vercel with self-hosted infrastructure.
npx skill4agent add nityeshaga/claude-code-essentials kamal-deployWebFetch(url: "https://kamal-deploy.org/docs/installation/", prompt: "Extract complete installation and setup guide")WebFetch(url: "https://kamal-deploy.org/docs/configuration/overview/", prompt: "Extract all configuration options and deploy.yml structure")WebFetch(url: "https://kamal-deploy.org/docs/commands/view-all-commands/", prompt: "Extract all Kamal commands and usage")WebFetch(url: "https://kamal-deploy.org/docs/configuration/proxy/", prompt: "Extract proxy, SSL, and health check configuration")https://kamal-deploy.org/docs/configuration/servers/https://kamal-deploy.org/docs/configuration/accessories/https://kamal-deploy.org/docs/configuration/environment-variables/https://kamal-deploy.org/docs/configuration/builders/https://kamal-deploy.org/docs/hooks/overview/https://kamal-deploy.org/docs/upgrading/overview/kamal versiongem install kamaltraefikproxybuilder:
arch: amd64
remote: ssh://root@SERVER_IP.env.erbop: command not found# Install (or upgrade)
gem install kamal
# Initialize in project
kamal init
# First deploy (installs Docker, proxy, deploys app)
kamal setup
# Subsequent deploys
kamal deploy| Command | Purpose |
|---|---|
| First deploy - installs Docker, proxy, deploys |
| Deploy new version |
| Revert to previous version |
| View application logs |
| SSH into running container |
| Start accessory (db, redis) |
| Restart kamal-proxy |
| Remove everything from servers |
service: my-app
image: username/my-app
servers:
- 123.45.67.89
registry:
username: username
password:
- KAMAL_REGISTRY_PASSWORD
proxy:
ssl: true
host: myapp.com
env:
secret:
- RAILS_MASTER_KEY
- DATABASE_URL.kamal/secrets# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=ghp_xxxxxxxxxxxx
RAILS_MASTER_KEY=abc123def456
DATABASE_URL=postgres://user:pass@db:5432/appenv:
clear:
RAILS_ENV: production
secret:
- RAILS_MASTER_KEY
- DATABASE_URLservers:
web:
hosts:
- 123.45.67.89
- 123.45.67.90
workers:
hosts:
- 123.45.67.91
cmd: bin/jobs
proxy: false # Workers don't need proxyaccessories:
db:
image: postgres:16
host: 123.45.67.89
port: 5432
env:
clear:
POSTGRES_DB: app_production
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
redis:
image: redis:7
host: 123.45.67.89
port: 6379
directories:
- data:/dataproxy:
ssl: true
host: myapp.com # Must point to server IPproxy:
ssl:
certificate_pem:
- SSL_CERTIFICATE
private_key_pem:
- SSL_PRIVATE_KEYproxy:
healthcheck:
interval: 3
path: /up
timeout: 3/upconfig/deploy.staging.ymlservers:
- staging.myapp.com
proxy:
host: staging.myapp.comkamal deploy -d staging.kamal/secrets.staging.kamal/hooks/pre-connectpre-buildpre-deploypost-deploypre-app-bootpost-app-bootpre-proxy-rebootpost-proxy-reboot.kamal/hooks/post-deploy#!/bin/bash
curl -X POST "https://api.honeybadger.io/v1/deploys" \
-d "deploy[revision]=$KAMAL_VERSION"FROM ruby:3.3-slim
WORKDIR /app
# Install dependencies
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
COPY Gemfile* ./
RUN bundle install
COPY . .
RUN bundle exec rails assets:precompile
EXPOSE 80
CMD ["bin/rails", "server", "-b", "0.0.0.0", "-p", "80"]/updeploy_timeoutkamal app logsssh-add ~/.ssh/id_rsaKAMAL_REGISTRY_PASSWORD.kamal/secretswrite:packageskamal proxy rebootdocker ps| Kamal | Kubernetes | Heroku | |
|---|---|---|---|
| Complexity | Low | High | None |
| Cost | VPS only | VPS + overhead | $$$ |
| Control | Full | Full | Limited |
| Zero-downtime | Yes | Yes | Yes |
| SSL | Auto | Manual | Auto |
| Learning curve | Hours | Weeks | Minutes |
docker build . && docker run -p 3000:80 <image>.kamal/secrets.gitignoreasset_path: /app/public/assets