DEV Community

Peon Sh
Peon Sh

Posted on Originally published at peon.sh

Deploying Ruby on Rails with Docker in 2026

Rails 8 ships Docker-ready. Deploy it to your own server with Postgres, Solid Queue and automatic SSL in under an hour.

Rails is Docker-native now
Since Rails 7.1, every new application generates a production-grade Dockerfile: multi-stage build, jemalloc for memory efficiency, Thruster in front of Puma for asset serving and compression, and a bootsnap-precompiled boot. The days of hunting for a community Rails Docker recipe are over; rails new output deploys as-is on any container platform.

Rails 8 doubled down on the single-server story with the Solid trilogy: Solid Queue (jobs), Solid Cache and Solid Cable all run on your relational database, which means a complete production Rails app can genuinely be two containers: web and Postgres.

The minimal production topology
Web service: your repo’s generated Dockerfile, deployed as a git app; Thruster listens on port 80 in-container
Postgres: managed database service on the same server, private network only, scheduled S3 backups
Optional worker: same image, command bin/jobs, only needed if you move job processing off the web container
No Redis required unless you add features that want it, Solid Queue and Solid Cache use Postgres
Secrets: the master key
Rails encrypts credentials.yml.enc in the repo and needs RAILS_MASTER_KEY to decrypt it at boot. Set that key as an encrypted environment variable in your platform dashboard, never bake it into the image or commit config/master.key. DATABASE_URL overrides database.yml, so wiring ActiveRecord to your managed Postgres is one variable.

A subtle build-time note: asset precompilation runs during the image build without real secrets; the generated Dockerfile uses a dummy SECRET_KEY_BASE for that stage, which is correct and safe.

Migrations and health checks
Run bin/rails db:migrate as the release command before each new container takes traffic. Rails 7.1+ ships a health endpoint at /up that returns 200 once the app boots, point the container health check at it and zero-downtime deploys gate on real readiness. Keep migrations backward-compatible with the running release (add columns nullable, backfill, tighten later) since old and new code overlap briefly during rollout.

Operating it
Push to deploy; watch the build in the dashboard; roll back in one click if a release misbehaves. Set the Postgres backup schedule (nightly, with 7 daily and 4 weekly retained, is a sane default) and test a restore once, before you need it. Logs stream from the container; RAILS_LOG_TO_STDOUT is already the containerized default.

Total bill for a production Rails app with database and backups: a $6 to $8 VPS plus $2 for the project. Compare that with the $50-plus a comparable managed dyno-and-Postgres pairing costs, with the same push-to-deploy workflow.

Top comments (0)