Claude-skill-registry deployment-kamal
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/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/deployment-kamal" ~/.claude/skills/majiayu000-claude-skill-registry-deployment-kamal && rm -rf "$T"
skills/data/deployment-kamal/SKILL.mdDeployment & 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:
- Installs Docker
- Configures the server
- Pulls your application image
- Starts containers
- Configures proxy
- Sets up SSL (via Let's Encrypt)
Subsequent deploys are just:
kamal deploy
Zero-Downtime Deploys
Kamal performs rolling deploys:
- Builds new Docker image
- Pushes to registry
- Pulls image on servers
- Starts new containers
- Waits for health check
- Shifts traffic to new containers
- 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
before using.config/ci.rb
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
- Use production environment with proper config
- Enable SSL/TLS (force_ssl = true)
- Set SECRET_KEY_BASE via credentials
- Use environment variables for secrets
- Enable caching (Solid Cache in Rails 8)
- Configure logging appropriately
- Set up monitoring (error tracking, metrics)
- Use CDN for assets
- Configure database connection pooling
- Set up backups (database, credentials)
See
references/production-checklist.md for complete checklist.
Further Reading
For deeper exploration:
: Complete Kamal deployment guidereferences/kamal-setup.md
: Production readiness checklistreferences/production-checklist.md
For code examples:
: Minimal single-server setupexamples/basic-config.yml
: No Docker Hub needed (Kamal 2.8+)examples/registry-free-config.yml
: Multiple web servers with workersexamples/multi-server-config.yml
: PostgreSQL and Redis setupexamples/with-accessories-config.yml
: Environment-specific deploysexamples/staging-production-config.yml
: Detailed health checksexamples/custom-healthcheck-config.yml
: Resource limits and scalingexamples/advanced-services-config.yml
: Pre/post deploy automationexamples/deployment-hooks.sh
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.