DocsRuby on Rails

Ruby on Rails

Deploy a Rails 7 app on Ruust: built with Nixpacks, served by Puma, with migrations run on every deploy.

Ruust hands your repo to Nixpacks, whose Ruby provider recognises a Rails app from the Gemfile and config.ru, installs Ruby, runs bundle install, and boots it under Puma. Your Egg is a real always-on server, so server-side rendering, Active Job workers and Action Cable websockets all run without cold starts. If you would rather control the image yourself, add a Dockerfile at the repo root and Ruust builds that instead (in which case Nixpacks is not involved).

Deploy it

  1. Push your Rails app to a Git repo.
  2. In the dashboard, choose New Egg and connect the repo.
  3. Set RAILS_MASTER_KEY (or SECRET_KEY_BASE) and DATABASE_URL on the Egg before you build.
  4. Pick a size and a region, then lay the Egg. Ruust builds it, precompiles assets, and hatches it on HTTPS.

Nixpacks runs bundle install for you. To compile your CSS and JavaScript into public/assets, run bundle exec rails assets:precompile as part of the build. With RAILS_ENV=production and SECRET_KEY_BASE set at build time (from RAILS_MASTER_KEY), precompilation runs cleanly.

The port

Ruust sets a PORT environment variable and your app must listen on it and bind to 0.0.0.0 (not localhost), or the Egg builds but never hatches. Add a Procfile at the repo root and bind Puma explicitly to tcp://0.0.0.0:$PORT; on the Nixpacks path the web: line is read by Nixpacks and baked into the image as the start command (it is ignored if you supply your own Dockerfile). The release: line runs once per deploy, after the build and before the new Egg hatches, so your schema stays in step with the code. If a migration fails, the release stops and the old Egg keeps serving.

text
web: bundle exec puma -b tcp://0.0.0.0:$PORT
release: bin/rails db:migrate
Procfile at the repo root: start Puma on PORT, and migrate on every deploy.

Environment variables

Set variables on the Egg (not in config/credentials): RAILS_ENV=production, RAILS_SERVE_STATIC_FILES=true so Puma serves your precompiled assets, DATABASE_URL for your database, and RAILS_MASTER_KEY (or a raw SECRET_KEY_BASE) to unlock encrypted credentials. They are available at build and run time, encrypted at rest, and never printed in logs.

Custom domains

Every Egg gets a <name>.<region>.ruust.run URL immediately. To serve your own domain, add it under the Egg and point the DNS record we show you; TLS is issued and renewed automatically by Caddy at the ingress tier. Set config.force_ssl = true in config/environments/production.rb to redirect any plain HTTP to HTTPS. Pin your Ruby version with a .ruby-version file (or the ruby line in your Gemfile): Nixpacks reads these and picks a matching Ruby, so local and Ruust builds match.