# Deploy Ruby on Rails

Rails is detected from your `Gemfile` and runs as a Ruby container on port `3000`. No Dockerfile needed - one is [generated](/platform/deployments/builds#dockerfiles-generated-or-your-own) unless the repo has its own (modern Rails ships one; it is used as written).

## Serve it

Puma binds the routed [port](/create/build-settings#port) via `PORT`, which is set for you - the stock `config/puma.rb` already reads it. Bind `0.0.0.0` (Puma's default in production).

## Configuration

Containers receive [environment variables](/platform/environment-variables#build-time-and-runtime) at runtime:

- `RAILS_ENV=production` and `SECRET_KEY_BASE` belong in the environment's variables.
- `RAILS_LOG_TO_STDOUT=1` sends logs where [runtime logs](/platform/observability#runtime-logs) can see them.

## Database

Rails reads `DATABASE_URL` natively - set it from the database's [Credentials tab](/platform/databases/connect) and `config/database.yml` needs no per-environment blocks. Point [previews](/platform/preview-environments) at a Shared-tier database by overriding the variable per environment.

Migrations run where the database is reachable - the startup command works:

```bash
bundle exec rails db:migrate && bundle exec puma -C config/puma.rb
```

## Assets

Precompile during the build so the image ships ready:

```bash
bundle exec rails assets:precompile
```

Set it as part of the [build command](/create/build-settings#build-command) if your setup doesn't already run it.

## Related

- [Connect an app](/platform/databases/connect): DATABASE_URL, TLS, per-environment databases.
- [Builds](/platform/deployments/builds): Generated images and bring-your-own Dockerfiles.
- [Scaling](/create/scaling): Instances, concurrency, and cold starts.
