PreviewDrop for Rails
Deploy previews for Ruby on Rails apps
Push a branch, get a live preview URL. PreviewDrop builds your Rails container and posts the link to the pull request in under 60 seconds — no CI scripts, no serverless rewrites.
TL;DR
Add a Dockerfile, connect your repo, push. PreviewDrop detects the push, builds the image, runs
db:migrate, and posts a TLS-terminated PR preview URL. Puma runs as a persistent process — Action Cable, background jobs, long-polling endpoints all work the same way they do in production.Dockerfile
Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.
DockerfileFROM ruby:3.3-slim RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY Gemfile Gemfile.lock ./ RUN bundle install --without development test COPY . . RUN SECRET_KEY_BASE=placeholder bundle exec rails assets:precompile RAILS_ENV=production EXPOSE 3000 CMD sh -c "bundle exec rails db:migrate && bundle exec rails server -b 0.0.0.0 -p ${PORT:-3000} -e production"
Environment variables
Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.
| Variable | Example value | Note |
|---|---|---|
| SECRET_KEY_BASE | $(bundle exec rails secret) | Required in production mode. Generate one with: bundle exec rails secret |
| RAILS_ENV | production | Set to production so Puma uses the correct config and assets are served. |
| RAILS_SERVE_STATIC_FILES | enabled | Rails disables static file serving in production by default. This env var re-enables it. |
| DATABASE_URL | postgres://user:pass@host:5432/db | Point at a shared dev DB or omit to use SQLite (fine for UI-only previews). |
Common gotchas
SECRET_KEY_BASE is required in production mode
Rails raises an error at startup if
SECRET_KEY_BASE is missing in production. Generate one with bundle exec rails secret and paste it into the PreviewDrop project variables. For previews, any long random string works — don't reuse your production secret.RAILS_SERVE_STATIC_FILES must be set
By default Rails does not serve static assets in production — it expects nginx to do that. PreviewDrop containers don't have nginx in front. Set
RAILS_SERVE_STATIC_FILES=enabled so the Puma process serves the precompiled assets itself.Asset precompilation needs a placeholder SECRET_KEY_BASE
The Dockerfile runs
assets:precompile at build time with a throw-away SECRET_KEY_BASE=placeholder. This is intentional — the real secret is injected at runtime, not baked into the image.Node.js required for asset pipeline
The Dockerfile installs
nodejs for Sprockets / importmap. If you use Webpacker or esbuild add yarn to the apt-get line and run your JS build step before assets:precompile.Why not Vercel or Netlify?
Rails is a long-running server process — not compatible with serverless functions. Action Cable (WebSockets), Sidekiq workers, long-polling endpoints, and multi-second requests don't fit the serverless model that Vercel and Netlify use for backend code. PreviewDrop runs your Dockerfile directly: Puma, Action Cable, background jobs — the full Rails stack as a PR deploy preview, with the same container shape as your production environment.
Preview your Rails app in 5 minutes
Connect a repo, push a branch, get a URL. No credit card, no trial clock.
Start free