Marketplace

Unnamed Skill

This skill should be used when the user asks about deploying Rails applications, Kamal deployment, Docker containers, production configuration, environment variables, secrets management, CI/CD pipelines, server provisioning, zero-downtime deploys, Kamal Proxy, Thruster, or infrastructure setup. Also use when discussing production optimization, deployment strategies, or hosting options. Examples:

$ 安裝

git clone https://github.com/sjnims/rails-expert /tmp/rails-expert && cp -r /tmp/rails-expert/plugins/rails-expert/skills/deployment-kamal ~/.claude/skills/rails-expert

// tip: Run this command in your terminal to install the skill


name: deployment-kamal description: This skill should be used when the user asks about deploying Rails applications, Kamal deployment, Docker containers, production configuration, environment variables, secrets management, CI/CD pipelines, server provisioning, zero-downtime deploys, Kamal Proxy, Thruster, or infrastructure setup. Also use when discussing production optimization, deployment strategies, or hosting options. Examples:

Deployment & Infrastructure: Kamal and Rails 8

Overview

Rails 8 ships with Kamal 2 for zero-downtime deployments to any Linux server. Kamal eliminates PaaS lock-in and Kubernetes complexity, giving you full control with simple tools.

Kamal philosophy:

  • Deploy to any server (VPS, cloud, on-premise)
  • Docker-based containers
  • Zero-downtime deploys
  • No vendor lock-in
  • Simple configuration
  • One command to deploy

Rails 8 also includes:

  • Thruster: Rust-based proxy for asset serving and compression
  • Kamal Proxy: Traffic routing and SSL termination
  • Dockerfile: Production-ready container configuration

Kamal Basics

What Kamal Does

Kamal turns a fresh Linux server into a production Rails host with a single command:

kamal setup

This:

  1. Installs Docker
  2. Configures the server
  3. Pulls your application image
  4. Starts containers
  5. Configures proxy
  6. Sets up SSL (via Let's Encrypt)

Subsequent deploys are just:

kamal deploy

Zero-Downtime Deploys

Kamal performs rolling deploys:

  1. Builds new Docker image
  2. Pushes to registry
  3. Pulls image on servers
  4. Starts new containers
  5. Waits for health check
  6. Shifts traffic to new containers
  7. Stops old containers

Users never see downtime.

Configuration

Kamal is configured in config/deploy.yml:

service: myapp
image: username/myapp

servers:
  web:
    hosts:
      - 192.168.1.1
      - 192.168.1.2

proxy:
  ssl: true
  host: myapp.com

registry:
  username: username
  password:
    - KAMAL_REGISTRY_PASSWORD

env:
  secret:
    - RAILS_MASTER_KEY

healthcheck:
  path: /up
  interval: 10s

Kamal 2 Features

Kamal Proxy

Rails 8 includes Kamal Proxy (replaces Traefik):

  • Simpler configuration
  • Better performance
  • Integrated health checks
  • Automatic SSL via Let's Encrypt
  • Traffic routing
  • Request buffering

Registry-Free Deploys (Rails 8.1+)

Kamal 2.8+ supports local registry for simple deploys:

# config/deploy.yml
registry:
  local: true  # No Docker Hub/GHCR needed

Perfect for getting started. Use remote registry for larger deployments.

Accessories

Deploy supporting services alongside your app:

accessories:
  db:
    image: postgres:16
    host: 192.168.1.1
    env:
      POSTGRES_PASSWORD: secret
    volumes:
      - /var/lib/postgresql/data:/var/lib/postgresql/data

  redis:
    image: redis:7
    host: 192.168.1.1

Rails 8 Dockerfile

Generated Dockerfile is production-ready:

FROM ruby:3.2-slim

# Install dependencies
RUN apt-get update && apt-get install -y \
  build-essential \
  postgresql-client \
  && rm -rf /var/lib/apt/lists/*

# Install gems
COPY Gemfile* ./
RUN bundle install

# Copy application
COPY . .

# Precompile assets
RUN bundle exec rails assets:precompile

# Start Thruster
CMD ["bin/thruster", "bin/rails", "server"]

Thruster

Rust-based proxy that sits in front of Puma:

Features:

  • X-Sendfile acceleration (serve files efficiently)
  • Asset caching (immutable assets cached forever)
  • Compression (gzip/brotli)
  • HTTP/2 support

Configuration:

# bin/thruster
thruster \
  --http-port=80 \
  --https-port=443 \
  --storage-path=/var/thruster \
  bin/rails server

Thruster handles all the performance optimizations you'd normally configure in Nginx.

Environment Configuration

Rails Environments

Rails has three default environments:

  • development: Local development (verbose logs, code reloading)
  • test: Running tests (separate database, fixtures)
  • production: Live application (caching, optimized, secure)

Configure in config/environments/:

# config/environments/production.rb
Rails.application.configure do
  config.cache_classes = true
  config.eager_load = true
  config.consider_all_requests_local = false
  config.public_file_server.enabled = true
  config.assets.compile = false
  config.assets.digest = true
  config.log_level = :info
  config.force_ssl = true
end

Secrets and Credentials

Rails 8 uses encrypted credentials:

# Edit credentials
rails credentials:edit

# Edit environment-specific credentials
rails credentials:edit --environment production
# config/credentials/production.yml.enc
secret_key_base: abc123...
database:
  password: dbpass
aws:
  access_key_id: AKIAIOSFODNN7EXAMPLE
  secret_access_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Access in code:

Rails.application.credentials.aws[:access_key_id]
Rails.application.credentials.database[:password]

Kamal can fetch secrets from credentials:

# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)

See references/kamal-setup.md for complete deployment guide.

CI/CD with Rails 8

Local CI (Rails 8.1+)

Note: This feature is available in Rails 8.1+. Verify your Rails version supports config/ci.rb before using.

Rails 8.1 includes built-in CI configuration:

# config/ci.rb
CI.run do
  step "Setup", "bin/setup --skip-server"
  step "Style: Ruby", "bin/rubocop"
  step "Security: Gem audit", "bin/bundler-audit"
  step "Tests: Rails", "bin/rails test"

  if success?
    step "Signoff: All systems go", "gh signoff"
  else
    failure "CI failed. Fix issues and try again."
  end
end

Run locally:

bin/ci

Perfect for fast feedback without cloud CI.

GitHub Actions

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres

    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      - run: bin/rails db:setup
      - run: bin/rails test
      - run: bin/rails test:system

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: webfactory/ssh-agent@v0.8.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - run: gem install kamal
      - run: kamal deploy

Production Best Practices

  1. Use production environment with proper config
  2. Enable SSL/TLS (force_ssl = true)
  3. Set SECRET_KEY_BASE via credentials
  4. Use environment variables for secrets
  5. Enable caching (Solid Cache in Rails 8)
  6. Configure logging appropriately
  7. Set up monitoring (error tracking, metrics)
  8. Use CDN for assets
  9. Configure database connection pooling
  10. Set up backups (database, credentials)

See references/production-checklist.md for complete checklist.

Further Reading

For deeper exploration:

  • references/kamal-setup.md: Complete Kamal deployment guide
  • references/production-checklist.md: Production readiness checklist

For code examples:

  • examples/basic-config.yml: Minimal single-server setup
  • examples/registry-free-config.yml: No Docker Hub needed (Kamal 2.8+)
  • examples/multi-server-config.yml: Multiple web servers with workers
  • examples/with-accessories-config.yml: PostgreSQL and Redis setup
  • examples/staging-production-config.yml: Environment-specific deploys
  • examples/custom-healthcheck-config.yml: Detailed health checks
  • examples/advanced-services-config.yml: Resource limits and scaling
  • examples/deployment-hooks.sh: Pre/post deploy automation

Summary

Rails 8 deployment provides:

  • Kamal 2: Zero-downtime deploys to any server
  • Thruster: Performance proxy
  • Kamal Proxy: Traffic routing
  • Dockerfile: Production-ready containers
  • Credentials: Encrypted secrets
  • Local CI: Fast feedback
  • Self-hosting: No vendor lock-in

Master Kamal and deploy with confidence to any infrastructure.