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:
- 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
config/ci.rbbefore 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
- 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:
references/kamal-setup.md: Complete Kamal deployment guidereferences/production-checklist.md: Production readiness checklist
For code examples:
examples/basic-config.yml: Minimal single-server setupexamples/registry-free-config.yml: No Docker Hub needed (Kamal 2.8+)examples/multi-server-config.yml: Multiple web servers with workersexamples/with-accessories-config.yml: PostgreSQL and Redis setupexamples/staging-production-config.yml: Environment-specific deploysexamples/custom-healthcheck-config.yml: Detailed health checksexamples/advanced-services-config.yml: Resource limits and scalingexamples/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.
Repository
