skills/backend/rails/8.0/SKILL.md
Version-specific expert for Rails 8.0 (November 2024). The 'No PaaS Required' release. Covers the Solid trilogy (Solid Queue, Solid Cache, Solid Cable), Kamal 2 deployment, authentication generator, Propshaft asset pipeline, Thruster HTTP/2 proxy, strict locals default, production SQLite configuration, and migration from 7.2. WHEN: "Rails 8.0", "Rails 8", "Solid Queue", "Solid Cache", "Solid Cable", "Kamal 2", "Kamal deploy", "Rails authentication generator", "Propshaft", "Thruster", "strict locals", "No PaaS Required", "importmap Rails 8", "production SQLite Rails", "migrate to Rails 8", "upgrade to Rails 8", "Kamal Proxy", "Rails 8 deployment".
npx skillsauth add chrishuffman5/domain-expert backend-rails-8-0Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a specialist in Rails 8.0 (GA November 2024, security fixes until November 2026). This is the "No PaaS Required" release -- its headline achievement is making Heroku/Render-style deployments unnecessary for most applications by bundling production-grade infrastructure tooling directly into the framework.
For foundational Rails knowledge (ActiveRecord, Action Pack, Turbo/Hotwire, testing), refer to the parent technology agent. This agent focuses on what is new, changed, or removed in 8.0.
| Milestone | Date | |---|---| | Release | November 2024 | | Bug fixes ended | May 2026 | | Security fixes end | November 2026 | | Minimum Ruby | 3.2.0 | | Recommended Ruby | 3.4.x |
Rails 8.0 introduced three database-backed infrastructure components that collectively eliminate Redis as a runtime dependency for most applications.
Traditional Rails deployments required Redis three times: caching, Action Cable pub/sub, and queue backend. The Solid trilogy replaces all three with SQL databases optimized for each task.
The Solid trilogy is not a universal Redis replacement. Keep Redis when:
Solid Queue replaces Redis + Sidekiq/Resque for background jobs. Uses FOR UPDATE SKIP LOCKED in PostgreSQL/MySQL for high-performance concurrent dispatch; falls back to sequential polling for SQLite.
# config/application.rb
config.active_job.queue_adapter = :solid_queue # default in Rails 8.0 new apps
# config/queue.yml
default: &default
dispatchers:
- polling_interval: 1
batch_size: 500
workers:
- queues: "*"
threads: 3
processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %>
polling_interval: 0.1
production:
<<: *default
workers:
- queues: [critical, default]
threads: 5
polling_interval: 0.1
processes: 2
- queues: [low]
threads: 2
polling_interval: 2
# config/database.yml (separate SQLite database for queue)
production:
primary:
<<: *default
database: storage/production.sqlite3
queue:
<<: *default
database: storage/production_queue.sqlite3
migrations_paths: db/queue_migrate
Features: recurring tasks (cron-like scheduling), concurrency controls, retries with backoff, pausing queues, web UI via mission_control-jobs. At 37signals (HEY), it processes 20 million jobs per day.
Replaces Redis/Memcached for fragment caching. Stores entries in the database using disk storage -- enabling much larger caches at lower cost.
# config/environments/production.rb
config.cache_store = :solid_cache_store
# config/database.yml
production:
cache:
<<: *default
database: storage/production_cache.sqlite3
migrations_paths: db/cache_migrate
Uses async writes, background expiry sweeper, and tracks hit/miss/size metrics. Can serve more cache requests per second than Redis for large HTML fragments because disk I/O is cheaper than Redis serialization overhead at scale.
Replaces the Redis pub/sub adapter for Action Cable WebSocket relay.
# config/cable.yml
production:
adapter: solid_cable
polling_interval: 0.1.seconds
message_retention: 1.day
# config/database.yml
production:
cable:
<<: *default
database: storage/production_cable.sqlite3
migrations_paths: db/cable_migrate
Suited for moderate real-time traffic. For very high-frequency WebSocket traffic (thousands of messages per second), Redis remains better.
Default deployment tool for new Rails 8 apps. Orchestrates Docker containers on any server with zero-downtime rolling deploys.
# config/deploy.yml (generated)
service: myapp
image: your-docker-hub/myapp
servers:
web:
- 192.168.1.100
job:
hosts:
- 192.168.1.100
cmd: bin/jobs
proxy:
ssl: true
host: myapp.example.com
registry:
username: your-docker-hub-username
password:
- KAMAL_REGISTRY_PASSWORD
env:
secret:
- RAILS_MASTER_KEY
- DATABASE_URL
volumes:
- "myapp_storage:/rails/storage"
accessories:
db:
image: postgres:16-alpine
host: 192.168.1.100
port: "127.0.0.1:5432:5432"
env:
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
Key Kamal 2 features:
kamal setup provisions servers, builds images, deployskamal setup # First-time provisioning
kamal deploy # Deploy new version
kamal rollback # Roll back to previous
kamal app logs # Tail logs
kamal app exec -i --reuse "bin/rails console" # Remote console
Built-in session-based authentication without any external gem dependency:
bin/rails generate authentication
Generated files:
app/models/user.rb # has_secure_password
app/models/session.rb # has_secure_token
app/models/current.rb # CurrentAttributes
app/controllers/concerns/authentication.rb
app/controllers/sessions_controller.rb
app/controllers/passwords_controller.rb
app/mailers/passwords_mailer.rb
db/migrate/xxx_create_users.rb
db/migrate/xxx_create_sessions.rb
Core pattern:
module Authentication
extend ActiveSupport::Concern
included do
before_action :require_authentication
helper_method :authenticated?
end
private
def require_authentication
resume_session || request_authentication
end
def resume_session
Current.session ||= find_session_by_cookie
end
def start_new_session_for(user)
user.sessions.create!(
user_agent: request.user_agent,
ip_address: request.remote_ip
).tap do |session|
Current.session = session
cookies.signed.permanent[:session_id] = {
value: session.id, httponly: true, same_site: :lax
}
end
end
end
Replaces Sprockets as the default. Philosophy: fingerprint and serve static assets. Deliberately does not compile Sass, transpile JS, or bundle files.
# Gemfile (Rails 8.0 new app)
gem "propshaft"
Propshaft with importmap:
<%= stylesheet_link_tag "application" %>
<%= javascript_importmap_tags %>
# config/importmap.rb
pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
Precompilation is ~92% faster than Sprockets (4s vs 48s) and uses 80% less memory. Existing Sprockets apps continue to work -- migration is opt-in.
Lightweight HTTP/2 proxy running in front of Puma inside the same container:
# Dockerfile (generated excerpt)
RUN gem install thruster
ENTRYPOINT ["/rails/bin/thrust", "./bin/rails", "server"]
Provides:
No Nginx required. Benchmarks show 25% faster initial page loads and up to 83% faster cache-miss loads under HTTP/2.
Strict locals (introduced in 7.1) are enabled by default. A magic comment enforces the variable contract:
<%# app/views/shared/_user_card.html.erb %>
<%# locals: (user:, show_email: false) %>
<div class="user-card">
<h3><%= user.name %></h3>
<%= user.email if show_email %>
</div>
ActionView::Template::Error<%# locals: () %> to declare a partial accepts no localsRails 8.0 ships production-ready SQLite defaults with WAL mode, busy timeouts, and proper connection settings:
# config/database.yml (SQLite production defaults)
production:
primary:
<<: *default
database: storage/production.sqlite3
queue:
<<: *default
database: storage/production_queue.sqlite3
migrations_paths: db/queue_migrate
cache:
<<: *default
database: storage/production_cache.sqlite3
migrations_paths: db/cache_migrate
cable:
<<: *default
database: storage/production_cable.sqlite3
migrations_paths: db/cable_migrate
WAL mode allows concurrent reads during writes, making SQLite viable for production with moderate traffic.
Deprecated in 7.x, fully removed in 8.0:
Railties:
config.read_encrypted_secrets (use Rails.application.credentials)Rails::ConsoleMethods extension patternActive Record:
config.active_record.commit_transaction_on_non_local_returnconfig.active_record.allow_deprecated_singular_associations_nameenum :status, active: 0)Active Support:
ActiveSupport::ProxyObjectAction Pack:
params.expect() is now preferred over some strong parameters patternsAction View:
nil to form_with model argumentAll features are opt-in for existing apps:
| Feature | How to Adopt |
|---|---|
| Solid Queue | config.active_job.queue_adapter = :solid_queue + install gem |
| Solid Cache | config.cache_store = :solid_cache_store + install gem |
| Solid Cable | Set adapter in cable.yml + install gem |
| Kamal | Add gem "kamal", run kamal init |
| Propshaft | Swap sprockets-rails for propshaft (test thoroughly) |
| Auth generator | bin/rails generate authentication |
# 1. Ruby version must be >= 3.2.0
# 2. Remove config.read_encrypted_secrets if present
# 3. Fix enum syntax
# Old: enum status: { active: 0, archived: 1 }
# New: enum :status, active: 0, archived: 1
# 4. Remove deprecated Active Record configs
# 5. Replace ActiveSupport::ProxyObject usage
# 6. Check gem compatibility (visit railsbump.org)
tools
kubectl command-line usage and scripting: kubeconfig and context management, output formats (jsonpath, custom-columns, go-template), all major verbs (get, describe, apply, delete, exec, logs, port-forward, rollout, scale, drain), workload resources, config/storage, networking, RBAC, node management, debugging (CrashLoopBackOff, ImagePullBackOff, OOMKilled), and scripting patterns (dry-run, diff, wait, jq, kustomize). WHEN: "kubectl", "k8s CLI", "kubeconfig", "namespace", "pod", "deployment", "service", "ingress", "configmap", "secret", "rollout", "scale", "drain", "taint", "kustomize". Do NOT use for cluster architecture, sizing, upgrades, or workload design decisions — that's the `kubernetes` skill in the `containers` plugin. This skill is command syntax and scripting kubectl against an existing cluster, not cluster ops.
tools
Bash 5.x shell scripting, Unix text processing, and command-line automation: variables, parameter expansion, quoting, control flow, functions, I/O redirection, error handling (set -euo pipefail, trap), and the Unix tool ecosystem (grep, sed, awk, jq, find, sort, uniq, cut, xargs). Covers process management, networking (curl, ssh, rsync, nc), file locking (flock), parallel execution, and production script patterns. WHEN: "Bash", "bash", "shell", "sh", ".sh", "shell script", "sed", "awk", "grep", "jq", "find", "xargs", "curl", "ssh", "rsync", "cron", "pipe", "redirect", "here-doc", "shebang", "POSIX", "set -euo pipefail", "trap".
tools
Azure CLI (az) command syntax and scripting: authentication (interactive, service principal, managed identity, SSO), output formats and JMESPath queries, resource groups, VMs, storage accounts/blobs, networking (VNets, NSGs, load balancers, DNS), Entra ID, AKS, App Service, Functions, databases (SQL, Cosmos DB, MySQL, PostgreSQL), Key Vault, Monitor/alerting, and infrastructure scripting patterns. WHEN: "az ", "Azure CLI", "az login", "az vm", "az aks", "az storage", "az keyvault", "az monitor", "az ad", "az group", "az network", "az webapp", "az functionapp", "az sql", "az cosmosdb", "JMESPath", "az account". Do NOT use for Azure architecture, landing zones, or multi-subscription strategy — that's the `cloud-platforms` plugin. This skill is about command syntax and scripting the CLI, not deciding what to provision.
tools
AWS CLI v2 command syntax and scripting: authentication (profiles, SSO, assume-role, instance profiles), output formats and JMESPath queries, pagination and waiters, IAM, S3, Lambda, RDS, CloudFormation, ECS, EKS, CloudWatch, SSM, Route 53, STS, and VPC networking. WHEN: "aws ", "AWS CLI", "aws ec2", "aws s3", "aws lambda", "aws iam", "aws cloudformation", "aws ssm", "aws ecs", "aws eks", "aws rds", "aws cloudwatch", "aws route53", "aws sts". Do NOT use for AWS architecture, service selection, multi-account strategy, or FinOps — that's the `cloud-platforms` plugin. This skill is about command syntax and scripting the CLI, not deciding what to provision.