Deploying Ruby on Rails
Convention-over-configuration Ruby framework with Puma, Kamal, or Heroku, plus asset pipeline and Sidekiq.
PlatformsAdvanced
Why
Rails' convention-over-configuration and rich defaults (ActiveRecord, ActionPack) enable rapid development. Kamal (formerly MRSK) provides zero-downtime Docker deploys to any server without Kubernetes.
Platform-as-a-Service adoption grew 24% in 2024 as teams shift from VM management to git-push deploys. the cloud infrastructure market reached $330B in 2024, growing 22% year-over-year (Synergy Research), and PaaS layers capture the majority of new workloads.
When
Use Rails for Ruby web apps, MVPs, and teams valuing developer happiness. Choose Kamal for VPS deploys; Heroku for simplicity.
How
1. Build — bundle install --deployment, RAILS_ENV=production bundle exec rake assets:precompile
2. Puma — bundle exec puma -C config/puma.rb, multi-worker web server
3. Kamal — kamal deploy, zero-downtime Docker to VPS via SSH
4. Heroku — git push heroku main, auto-builds with buildpacks
5. DB — rails db:migrate on deploy (release phase on Heroku)
6. Sidekiq — bundle exec sidekiq for async jobs, Redis required
7. Env — RAILS_ENV=production, SECRET_KEY_BASE, DATABASE_URL
Example
# Dockerfile — Rails + Puma
FROM ruby:3.3-slim AS build
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install --deployment
COPY . .
RUN RAILS_ENV=production bundle exec rake assets:precompile
FROM ruby:3.3-slim
WORKDIR /app
COPY --from=build /app /app
EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
# config/puma.rb — production
workers ENV.fetch("WEB_CONCURRENCY", 2).to_i
threads_count = ENV.fetch("RAILS_MAX_THREADS", 5).to_i
threads threads_count, threads_count
preload_app!
# config/deploy.yml — Kamal
service: myapp
image: myuser/myapp
servers:
- 203.0.113.10
env:
clear:
RAILS_ENV: production
secret:
- DATABASE_URL
- SECRET_KEY_BASE
Common Problems
- ⚠Assets missing in production — forgot assets:precompile or config.assets.compile=false
- ⚠Puma single worker — not using WEB_CONCURRENCY, only one CPU core utilized
- ⚠Sidekiq jobs silently fail — Redis not configured or Sidekiq process not running
Best Practices
- ✓Use Kamal for zero-downtime Docker deploys to VPS — simpler than Kubernetes, no extra infra
- ✓Set preload_app! in Puma — saves memory by sharing code between workers via copy-on-write
- ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit