Deployment

Website Rebuild with Ruby on Rails

Chapter 11 · Deployment

This chapter covers two genuinely separate stories: Rails' own distinct approach to secrets management, and a real, mechanically different version of this series' own "modernize in place" throughline.

Secrets: A Reversed Philosophy

rails credentials:edit
The opposite of the .env pattern
Every sibling course kept its own secrets in a .env file, deliberately excluded from the repository via .gitignore. Rails takes the reverse approach: config/credentials.yml.enc holds the actual secrets, encrypted, and is committed to the repository as ordinary source. config/master.key — the one file that can decrypt it — is what's excluded from the repo instead. Rather than keeping the secrets themselves out of version control, Rails keeps them in, encrypted, and protects only the single key that unlocks them.

RAILS_MASTER_KEY is set as a real environment variable on the production server, letting the running application decrypt credentials.yml.enc at boot — the deployment's own equivalent of the legacy site's admin credential needing to be present somewhere, just moved to protecting one small key file instead of an entire secrets file.

Allowed Hosts — A Genuine Parallel, Not a Difference

# config/environments/production.rb config.hosts << "osztromok.com"

Rails' own config.hosts is a genuine, direct parallel to Django's ALLOWED_HOSTS — both protect against HTTP Host header attacks by rejecting requests for domains the application doesn't recognize as its own. Worth naming honestly as a real similarity, not manufactured as a difference.

Deployment: Phusion Passenger's Apache Module

# Apache VirtualHost — the site's own already-running Apache <VirtualHost *:443> ServerName osztromok.com DocumentRoot /var/www/rails-rebuild/public PassengerEnabled on PassengerRuby /usr/bin/ruby3.2 SSLEngine on SSLCertificateFile /etc/letsencrypt/live/osztromok.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/osztromok.com/privkey.pem </VirtualHost>

PassengerEnabled on and PassengerRuby are essentially the entire configuration. There's no separate reverse-proxy directive to write.

A different mechanism, not just a different config file
Laravel's own mod_proxy_fcgi reuse still proxies — Apache forwards PHP requests over a socket to an independently-running PHP-FPM process pool, a real separate process Apache talks to. Phusion Passenger's own Apache module (mod_passenger) works differently: it embeds Ruby process spawning and supervision directly into Apache's own module system, with Apache itself managing the Rails application processes as a native extension of itself, no separate proxy hop involved. Both reuse the site's own already-live Apache, giving this course its own honest version of the "modernize in place" story — but the two are genuinely different mechanisms, not the same idea in a different config syntax.
Named honestly: not the more common modern choice
The more common production setup for a modern Rails application is standalone Puma (Rails' own default app server, bundled in the Gemfile already) running behind nginx as a reverse proxy — genuinely the more typical path most current Rails deployment guides recommend. Passenger is chosen here specifically because it lets this chapter continue the same "reuse what's already live" throughline as Laravel's own deployment chapter, not because it's the field's dominant default.

Assets & Migrations

RAILS_ENV=production rails assets:precompile RAILS_ENV=production rails db:migrate

assets:precompile runs Propshaft's own fingerprinting step, established in Chapter 5 — no separate Node/npm build pipeline to coordinate, exactly as that chapter's own forward reference promised.

Four Frameworks' Secrets & Deployment, Compared

Next.js / Django / LaravelRails
Secrets storagePlain .env, excluded from the repoEncrypted credentials.yml.enc, committed to the repo; only the key is excluded
Reused Apache reverse-proxy mechanismN/A / N/A / mod_proxy_fcgi, proxying to PHP-FPMmod_passenger, embedding process management directly into Apache

Hands-On Exercises

Exercise 1

Explain what config/credentials.yml.enc and config/master.key are, and explain why Rails' own secrets-management approach is the reverse of the .env-file pattern every sibling course used.

📄 View solution
Exercise 2

Explain the real mechanical difference between Phusion Passenger's Apache module and Laravel's own mod_proxy_fcgi reuse of the site's already-live Apache.

📄 View solution
Exercise 3

Explain why this chapter names Puma-behind-nginx honestly as the more common modern Rails deployment choice, rather than presenting Passenger as simply the correct or superior option.

📄 View solution

Chapter 11 Quick Reference

  • config/credentials.yml.enc + config/master.key — encrypted secrets committed to the repo; only the key stays out
  • config.hosts — a genuine parallel to Django's ALLOWED_HOSTS, not a difference
  • PassengerEnabled on — embeds Ruby process management directly into Apache, mechanically different from proxying to PHP-FPM
  • Honest alternative — Puma-behind-nginx is the more common modern choice; Passenger is used here for the "modernize in place" throughline specifically
  • rails assets:precompile — Chapter 5's Propshaft payoff, no separate JS build step needed
  • Next chapter: Capstone — A Complete, Working Flexible-Routing Site