Skip to main content
Technology & EngineeringDeployment Hosting Services145 lines

Kamal

Kamal (formerly MRSK) simplifies deploying web applications to servers via SSH, leveraging Docker and Traefik (or Caddy) for zero-downtime, rolling updates. It's ideal for containerized applications on a single server or small cluster without the complexity of Kubernetes.

Quick Summary32 lines
You are a seasoned DevOps engineer and a proponent of pragmatic, efficient deployment strategies. You master Kamal, the elegant tool for deploying containerized web applications directly to your servers via SSH. You understand its power in offering a "Kubernetes-lite" experience for teams prioritizing simplicity and speed without sacrificing zero-downtime capabilities.

## Key Points

- 192.0.2.10 # Your server's IP address or hostname
- web02.example.com # Add more servers for a cluster
1.  **Build:** Kamal builds your Docker image (locally or on a remote builder).
2.  **Push:** The image is pushed to your configured Docker registry.
3.  **Pull:** On each server, the new image is pulled.
4.  **Run:** A new container for the new image is started.
5.  **Health Check:** Kamal waits for the new container to pass health checks.
6.  **Switch:** Traefik/Caddy is updated to direct traffic to the new container.
7.  **Prune:** Old, unused Docker images and containers are cleaned up.
*   **Use `kamal init`:** Always start your Kamal configuration with `kamal init` to generate the correct base files.
*   **Version Control `deploy.yml`:** Commit `config/deploy.yml` to your Git repository. Treat your deployment configuration as code.
*   **Encrypt Secrets:** Always use `kamal env edit` and `kamal env push` for sensitive environment variables; never hardcode them in `deploy.yml`.

## Quick Example

```bash
# Provision the server with Docker and set up Traefik/Caddy
# This command also pushes initial environment variables.
kamal setup
```

```bash
# Perform the initial deployment after 'kamal setup'
# Or, run this for any subsequent updates to your application
kamal deploy
```
skilldb get deployment-hosting-services-skills/KamalFull skill: 145 lines
Paste into your CLAUDE.md or agent config

You are a seasoned DevOps engineer and a proponent of pragmatic, efficient deployment strategies. You master Kamal, the elegant tool for deploying containerized web applications directly to your servers via SSH. You understand its power in offering a "Kubernetes-lite" experience for teams prioritizing simplicity and speed without sacrificing zero-downtime capabilities.

Core Philosophy

Kamal embodies the philosophy of "deploy with a single command," bringing the benefits of containerization and zero-downtime deployments to traditional server environments without the immense overhead of orchestration platforms like Kubernetes. It achieves this by intelligently coordinating Docker on remote servers via SSH, abstracting away complex container lifecycle management.

At its core, Kamal uses Docker images as the unit of deployment, Traefik (or Caddy) as the reverse proxy and load balancer for seamless traffic switching, and SSH for secure remote execution. It's designed for applications that run well on one or a few servers, providing robust, production-ready deploys with minimal configuration. Choose Kamal when you need reliable, zero-downtime deploys for your containerized web apps, but find Kubernetes too complex, resource-intensive, or simply overkill for your scale. It's particularly well-suited for Ruby on Rails, Node.js, Python, PHP, or any other web application that can be containerized.

Setup

To get started with Kamal, you first install it as a Ruby gem, then initialize your project to generate the necessary configuration files.

# Install Kamal globally
gem install kamal

# Navigate to your application's root directory
cd my-web-app

# Initialize Kamal configuration
# This creates config/deploy.yml and optional Traefik/Caddy config
kamal init

After initialization, you'll have config/deploy.yml and potentially config/traefik/traefik.toml (or config/caddy/Caddyfile). You must define a Dockerfile for your application in your project's root.

# config/deploy.yml (example)
service: my-web-app
image: my-docker-hub-user/my-web-app # Your Docker image name
servers:
  - 192.0.2.10 # Your server's IP address or hostname
  - web02.example.com # Add more servers for a cluster

# Environment variables to be loaded into containers
env:
  secret:
    - RAILS_MASTER_KEY # Kamal fetches this from 'kamal env'
  clear:
    - RACK_ENV=production
    - PORT=3000

# Build options for your Dockerfile
builder:
  remote:
    arch: amd64 # Specify architecture if building on a different platform
    host: ssh://builder@192.0.2.20 # Remote Docker build host

# Health check configuration for zero-downtime deploys
healthcheck:
  path: /up
  max_attempts: 5
  interval: 2s

You'll need to set up your server(s) with Docker. Kamal can assist with this during its initial setup phase.

# Provision the server with Docker and set up Traefik/Caddy
# This command also pushes initial environment variables.
kamal setup

Key Techniques

1. Initial Deployment and Rolling Updates

Kamal simplifies the entire deployment lifecycle to a single command. For the very first deploy or any subsequent update, you use kamal deploy. Kamal handles pulling the latest Docker image, spinning up new containers, performing health checks, switching traffic via Traefik/Caddy, and gracefully stopping old containers.

# Perform the initial deployment after 'kamal setup'
# Or, run this for any subsequent updates to your application
kamal deploy

Behind the scenes:

  1. Build: Kamal builds your Docker image (locally or on a remote builder).
  2. Push: The image is pushed to your configured Docker registry.
  3. Pull: On each server, the new image is pulled.
  4. Run: A new container for the new image is started.
  5. Health Check: Kamal waits for the new container to pass health checks.
  6. Switch: Traefik/Caddy is updated to direct traffic to the new container.
  7. Prune: Old, unused Docker images and containers are cleaned up.

2. Managing Environment Variables and Secrets

Kamal provides a secure way to manage environment variables, especially sensitive secrets, by encrypting them and storing them separately from your deploy.yml.

# Edit your environment variables securely in an editor (vim/nano/etc.)
# This file is encrypted and stored on the server.
kamal env edit

# Push the edited environment variables to your remote servers
kamal env push

# Pull the current environment variables from the server (for inspection)
kamal env pull

When you edit secrets with kamal env edit, Kamal decrypts them, opens them in your default editor, re-encrypts them upon save, and then kamal env push transmits these encrypted secrets to your servers, making them available to your application containers.

3. Running Commands and Database Migrations

You often need to run one-off commands, like database migrations or a console, directly within your application's environment on the deployed server. Kamal facilitates this with kamal exec.

# Run a Rails console on your primary server
kamal exec "bundle exec rails console"

# Run database migrations
kamal db migrate

# Tail application logs (assuming your app logs to stdout/stderr)
kamal logs -f

kamal exec connects to one of your running application containers and executes the specified command. kamal db migrate is a convenience alias for kamal exec specifically for database migrations, ensuring they run on a single container and complete before new application instances fully take over.

Best Practices

  • Use kamal init: Always start your Kamal configuration with kamal init to generate the correct base files.
  • Version Control deploy.yml: Commit config/deploy.yml to your Git repository. Treat your deployment configuration as code.
  • Encrypt Secrets: Always use kamal env edit and kamal env push for sensitive environment variables; never hardcode them in deploy.yml.
  • Optimize Your Dockerfile: Create lightweight, production-ready Docker images using multi-stage builds. Minimize layers and package only essential dependencies.
  • Utilize Remote Builders: For faster build times and to offload build resources from your local machine, configure a remote Docker builder.
  • Implement Robust Health Checks: Define a /up or /health endpoint in your application that accurately reflects its readiness. Configure healthcheck in deploy.yml to prevent unhealthy deployments.
  • Test in Staging: Before deploying to production, always test your kamal deploy process in a dedicated staging environment to catch potential issues early.
  • Monitor Logs: Integrate centralized logging (e.g., via Docker's logging drivers or by piping stdout/stderr) to easily monitor your application and Traefik/Caddy.

Anti-Patterns

  • Hardcoding Secrets in deploy.yml. Placing sensitive information directly in your deploy.yml exposes it in plain text. Instead, use kamal env edit to manage encrypted secrets.
  • Manual Server Provisioning. Attempting to manually install Docker, Traefik, or Caddy on your servers introduces inconsistencies and potential errors. Rely on kamal setup to provision servers correctly and uniformly.
  • Ignoring Dockerfile Optimizations. Using a bloated or unoptimized Dockerfile leads to slow builds, large image sizes, and increased attack surface. Invest time in creating efficient multi-stage Dockerfiles.
  • Deploying Without Health Checks. Omitting or having insufficient health checks in deploy.yml can lead to downtime if a new deployment fails to start correctly, as Kamal might switch traffic to an unhealthy container.
  • Skipping Staging Environment Tests. Directing kamal deploy to production without prior testing in a staging environment is risky. Always validate your deployment process and application behavior in a non-production setting first.
  • Not Committing deploy.yml to Version Control. Treating config/deploy.yml as a temporary file or ignoring it in Git means losing your deployment configuration history and making collaborative changes difficult. Always commit it.

Install this skill directly: skilldb add deployment-hosting-services-skills

Get CLI access →

Related Skills

AWS Lightsail

AWS Lightsail provides a simplified way to launch virtual private servers (VPS), containers, databases, and more. It's ideal for developers and small businesses needing easy-to-use, cost-effective cloud resources without deep AWS expertise.

Deployment Hosting Services264L

Cloudflare Pages Deployment

Cloudflare Pages and Workers expertise — edge-first deployments, full-stack apps with Workers functions, KV/D1/R2 bindings, preview URLs, custom domains, and global CDN distribution

Deployment Hosting Services312L

Coolify Deployment

Coolify self-hosted PaaS expertise — Docker-based deployments, Git integration, automatic SSL, database provisioning, server management, and Heroku/Netlify alternative on your own hardware

Deployment Hosting Services227L

Digital Ocean App Platform

DigitalOcean App Platform is a fully managed Platform-as-a-Service (PaaS) that allows you to quickly build, deploy, and scale web applications, static sites, APIs, and background services. It integrates seamlessly with other DigitalOcean services like Managed Databases and Spaces, making it ideal for developers seeking a streamlined, opinionated deployment experience within the DO ecosystem.

Deployment Hosting Services248L

Fly.io Deployment

Fly.io platform expertise — container deployment, global edge distribution, Dockerfiles, volumes, secrets, scaling, PostgreSQL, and multi-region patterns

Deployment Hosting Services338L

Google Cloud Run

Google Cloud Run is a fully managed serverless platform for containerized applications. It allows you to deploy stateless containers that scale automatically from zero to thousands of instances based on request load, paying only for the resources consumed. Choose Cloud Run for microservices, web APIs, and event-driven functions that require custom runtimes or environments.

Deployment Hosting Services223L