Rails apps on sub-URIs thanks to Passenger

Gregory Durelle
Mar 7, 2016 · 2 min read

Phusion Passenger offers a trivial feature but yet impossible to do without it: Applications served on sub-uris on the same subdomain.

  • projects.example.com/myproject
  • projects.example.com/my_other_project

Of course you need to install passenger first: https://www.phusionpassenger.com/library

I suggest you install its custom Nginx integrated version in order to use it for other purpuses without hassle.

Now that Passenger is installed, create a projects file in /etc/nginx/sites-available

Nginx : projects.example.com

Paste this (and customize it of course) in the projects file:

server {
listen *:80;
listen [::]:80;
server_name projects.example.com;
server_tokens off;
return 301 https://$server_name$request_uri;
}
server {
listen 0.0.0.0:443 ssl;
listen [::]:443;
server_name projects.example.com;
server_tokens off;
# passenger_enabled on; location ~ ^/myproject(/.*|$) {
alias /srv/www/myproject/current/public$1;
passenger_base_uri /myproject;
passenger_app_root /srv/www/myproject/current;
passenger_document_root /srv/www/myproject/current/public;
passenger_enabled on;
}
location ~ ^/my_other_project(/.*|$) {
alias /srv/www/my_other_project/current/public$1;

passenger_base_uri /my_other_project;
passenger_app_root /srv/www/my_other_project/current;
passenger_document_root /srv/www/my_other_project/current/public;
passenger_enabled on;
}
client_max_body_size 250m; ssl on;

ssl_certificate /etc/letsencrypt/live/projects.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/projects.example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_dhparam /etc/nginx/ssl/certs/dhparam.pem;
add_header Strict-Transport-Security “max-age=15768000;
includeSubDomains”;
error_page 502 /502.html;
}

The tricks are:

  • Do not enable passenger in the server block.
  • Do enable passenger for each location block.
  • Use alias instead of root on the location blocks.

To test if your configuration is ok:

sudo service nginx -t

When ready create the symlink in /etc/nginx/sites-enabled and restart nginx

sudo service nginx restart

DONE !

You might have noticed lot of other unrelated fields in our Nginx configuration file. It’s the configuration as suggested by Mozzila’s TLS configuration config generator.

I’ll explain more about these in a later post.

Nginx.conf

In case you need it, here is the major part of my /etc/nginx/nginx.conf file:

http { ##
# SSL Settings
##
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK’;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
##
# Phusion Passenger config
##
# Uncomment it if you installed passenger or passenger-enterprise
##
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /home/gdurelle/.rbenv/versions/2.2.3/bin/ruby;
}

There will be more in yours ! I removed some configs (basics, logs, hosts includes, gzip, etc) for reading purposes, they DO exists in the real config file, so do not erase lines you do not see here ;)

Again, the SSL lines you can see here comes from Mozilla’s generator, I placed them in the nginx.conf file so that all other nginx sites-enabled configs will inherit form it.

The Ruby on Rails application

The only thing you have to add in your Rails application is in the environnement/production.rb file:

config.action_controller.relative_url_root = “/myproject”

Thus the generated URLs will be right.

Gregory Durelle

Written by

French engineer passioned by new technologies, UX and learning things...

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade