← Blog

Deploying Rails without writing a Dockerfile

Railyard

February 24, 2026

The assumption behind most “how to containerize Rails” guides is that you need to write a Dockerfile first. Most of the time you don’t — the build method only needs to become your problem when the defaults genuinely can’t figure out your app, which is rarer than it sounds.

What actually picks the build method

MethodWhen it runs
Dockerfilethe repo has one that actually builds the app — a dev-only Dockerfile expecting a bind mount gets skipped automatically, not blindly run
Railpackthe default for any repo without a Dockerfile
Nixpacksfallback when Railpack can’t plan the repo
Buildpacksonly when chosen explicitly under Settings → Build method

A fresh Rails app with no Dockerfile builds on Railpack with nothing written by hand. The ordering matters more than the names: Railyard checks for a real Dockerfile first, and only reaches for the automatic builders when there isn’t one.

What a Rails app gets without being asked

This is the part that replaces what a hand-written Dockerfile would otherwise need to do:

  • RAILS_ENV, RACK_ENV, RAILS_SERVE_STATIC_FILES and RAILS_LOG_TO_STDOUT get set if you haven’t already.
  • Assets build with SECRET_KEY_BASE_DUMMY=1, so a real secret isn’t required at build time — SECRET_KEY_BASE itself gets generated once and encrypted.
  • pg, mysql2/trilogy, and redis/sidekiq in the Gemfile map to the matching managed database — Rails 8’s extra databases (cache, queue, cable) declared in config/database.yml each get their own connection URL automatically.
  • Sidekiq, Solid Queue, GoodJob, Resque or Delayed Job — whichever is actually in the Gemfile.lock — gets offered as the worker process.
  • Active Storage on disk gets a persistent volume with no setup; attach a bucket instead and the S3 variables get injected the same way.
  • assets:precompile runs in the build step automatically, Node toolchain included — a tailwindcss:build or esbuild step chained onto it just works, no separate Dockerfile stage.

When you actually need to write one

A Dockerfile earns its place when the app depends on something genuinely outside Ruby’s own ecosystem — a compiled binary the automatic builders don’t know to install, a non-standard runtime step, a base image mandated for compliance reasons. Short of that, the automatic path handles old native gems (nio4r, Puma 5 and earlier) compiling cleanly under current GCC without any Dockerfile changes.

The release step runs bin/rails db:prepare before each version takes traffic by default — a Procfile’s own release: line overrides it if you’ve already got one. Set a custom release_command only when db:prepare genuinely isn’t enough, like a one-off data migration script.

Full framework reference: Rails, and what the build step actually does: Build methods.

Deploy a Rails app from a bare repo.

Paste the Git URL — Railyard reads the Gemfile and fills in the process list, databases and variables itself.

Free plan, no card, and 14 days of Pro for every new team. One flat price per team.