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.
This skill inherits all available tools. When active, it can use any tool Claude has access to.
examples/advanced-services-config.ymlexamples/basic-config.ymlexamples/custom-healthcheck-config.ymlexamples/deployment-hooks.shexamples/multi-server-config.ymlexamples/registry-free-config.ymlexamples/staging-production-config.ymlexamples/with-accessories-config.ymlreferences/kamal-setup.mdreferences/production-checklist.mdRails 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:
Rails 8 also includes:
Kamal turns a fresh Linux server into a production Rails host with a single command:
kamal setup
This:
Subsequent deploys are just:
kamal deploy
Kamal performs rolling deploys:
Users never see downtime.
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
Rails 8 includes Kamal Proxy (replaces Traefik):
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.
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
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"]
Rust-based proxy that sits in front of Puma:
Features:
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.
Rails has three default environments:
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
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.
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/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
See references/production-checklist.md for complete checklist.
For deeper exploration:
references/kamal-setup.md: Complete Kamal deployment guidereferences/production-checklist.md: Production readiness checklistFor 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 automationRails 8 deployment provides:
Master Kamal and deploy with confidence to any infrastructure.