Gemfile, so no Dockerfile is needed.
This guide explains how to deploy a Rails app with Postgres in two ways:
Your repo needs a standard Rails layout: a Gemfile listing rails, puma, and pg, a Gemfile.lock, and the usual config/, app/, and bin/ folders.
The guide assumes config/database.yml reads DATABASE_URL in the production section (Rails’ default template does), Puma is your web server, and db:prepare handles migrations.
Deploy using the Canvas
Create a project from your repo
Add Postgres from a template
POSTGRES_USER and POSTGRES_DB (both default to postgres) and pre-fills a generated POSTGRES_PASSWORD./var/lib/postgresql.Expose the app on HTTPS
3000. Then, in the Public Network section, click Add Endpoint → HTTPS Domain and choose port 3000.Wire DATABASE_URL and Rails production settings
DATABASE_URL env var. Set the value to a connection string with an embedded reference to Postgres’s password:{{...}} picker inserts the reference alongside literal text, so the app reads the password from postgres at deploy time without duplicating it. Swap the user and database name if you changed them from the defaults.Then add three literal env vars so Rails runs in production mode without a separate log or static-file server:RAILS_ENV:productionRAILS_LOG_TO_STDOUT:trueRAILS_SERVE_STATIC_FILES:true

Apply to deploy
SECRET_KEY_BASE as a Sensitive env var on the app container (generate one with bundle exec rails secret or openssl rand -hex 64). If your app uses encrypted credentials, add RAILS_MASTER_KEY instead, matching the contents of config/master.key. Then click Apply in the top right.Suga clones the app repo, runs bundle install, starts Puma on port 3000, and rolls out both containers. The Rails app is served at the public URL and reaches Postgres privately at postgres:5432. Hit the root URL and you’ll see:Deploy using an Agent
To deploy with a coding agent such as Claude Code, Codex, or OpenCode, follow these steps:Connect the Suga MCP
Ask your agent to deploy
Set the sensitive values
POSTGRES_PASSWORD on the postgres container: click the value input and paste a value generated with openssl rand -hex 32. On the app container, add SECRET_KEY_BASE as a Sensitive env var (generate one with bundle exec rails secret), or RAILS_MASTER_KEY matching your config/master.key if you use encrypted credentials.Apply to deploy
bundle install, applies migrations, starts Puma on port 3000, and rolls out both containers. The Rails app is served at the public URL and reaches Postgres privately at postgres:5432. Hit the root URL and you’ll see:FAQ
Do I need a Dockerfile to deploy Rails on Suga?
Do I need a Dockerfile to deploy Rails on Suga?
Gemfile and runs the standard install and start flow. If you already have a Dockerfile, you can tell the agent to use it instead; otherwise auto-detect handles the common case.Which Ruby versions does Suga support?
Which Ruby versions does Suga support?
Gemfile (ruby "x.y.z"), .ruby-version, or .tool-versions if present, and falls back to a recent stable release.What if my start command isn't bundle exec rails server?
What if my start command isn't bundle exec rails server?
RAILPACK_START_CMD as a build arg on the app container with your exact command. Common alternatives: bundle exec puma -C config/puma.rb for a custom Puma config, bundle exec unicorn -c config/unicorn.rb -p 3000 for Unicorn, bundle exec passenger start -p 3000 for Passenger, or bundle exec thin -p 3000 for Thin. Suga only cares that something listens on the container’s private port.How do I run migrations before the app starts?
How do I run migrations before the app starts?
db:prepare: pass RAILPACK_START_CMD=bundle exec rails db:prepare && bundle exec rails server -b 0.0.0.0 -p 3000 as a build arg. db:prepare creates the database if it doesn’t exist and applies pending migrations, so it’s safe on first boot and idempotent afterward.Can I skip auto-migrations at boot?
Can I skip auto-migrations at boot?
bundle exec rails db:prepare && prefix from RAILPACK_START_CMD and run migrations manually — from the container’s shell in the dashboard, or from your CI pipeline before you Apply. Running migrations at boot is convenient, but teams with strict migration workflows often prefer to trigger them explicitly.What if my app is on Rails older than 6.1 and doesn't have db:prepare?
What if my app is on Rails older than 6.1 and doesn't have db:prepare?
bundle exec rails db:create db:migrate instead: pass RAILPACK_START_CMD=bundle exec rails db:create db:migrate && bundle exec rails server -b 0.0.0.0 -p 3000 as a build arg. db:create no-ops if the database already exists, so it’s safe to run on every boot.How do I use RAILS_MASTER_KEY for encrypted credentials?
How do I use RAILS_MASTER_KEY for encrypted credentials?
RAILS_MASTER_KEY as a Sensitive env var on the app container, with the value matching your local config/master.key. Rails reads it at boot to decrypt config/credentials.yml.enc, so anything referenced from Rails.application.credentials becomes available.Are assets precompiled during the build?
Are assets precompiled during the build?
bundle exec rails assets:precompile as part of the build when it detects an app/assets/ directory or the sprockets-rails gem. Precompiled assets are baked into the image, so RAILS_SERVE_STATIC_FILES=true is enough to serve them without a separate nginx.What if my asset pipeline uses Vite, Webpacker, or esbuild-rails?
What if my asset pipeline uses Vite, Webpacker, or esbuild-rails?
RAILPACK_BUILD_CMD as a build arg on the app container to run the JavaScript build followed by assets:precompile. Examples: bundle exec rails javascript:build && bundle exec rails assets:precompile for jsbundling-rails (esbuild, rollup, or bun), bundle exec vite build && bundle exec rails assets:precompile for vite_rails, or bundle exec rails webpacker:compile && bundle exec rails assets:precompile for Webpacker. Precompiled output lands in public/assets/ and RAILS_SERVE_STATIC_FILES=true serves it.Can I use multiple databases (Rails 6+ multi-database)?
Can I use multiple databases (Rails 6+ multi-database)?
config/database.yml reads (e.g. PRIMARY_DATABASE_URL, REPLICA_DATABASE_URL). Reference each container’s POSTGRES_PASSWORD in the corresponding URL. The cross-container reference works for any number of databases.How do I run Sidekiq or a background worker?
How do I run Sidekiq or a background worker?
RAILPACK_START_CMD=bundle exec sidekiq. Set the same DATABASE_URL and any Redis env vars, and leave it with no public endpoint. Add a Redis container from the template for the Sidekiq broker.What about Postgres backups?
What about Postgres backups?
pg_dump on a schedule from another container, or point the app at a managed Postgres service instead of a container.Can I use a custom domain?
Can I use a custom domain?
What does deploying Rails plus Postgres cost on Suga?
What does deploying Rails plus Postgres cost on Suga?