Rails - access a subdomain app via the root domain in Plesk Onyx

I ran into just this problem the other day. Migrating my Rails store from a CPanel VPS over to the current Plesk Onyx VPS proved to be a little tricky. It took me a while to figure out a solution. So I figured I’d write a blog outlining the steps I took to get my desired result.

The problem

For the sake of simplicity, I like to host my Store as a subfolder of my root domain. ie https://sweetpproductions.com/store. In Cpanel, this was pretty easy to set up. Just add a symlink from sweetpproductions/store to the Rails app directory. Soon I found out, this is not so simple in Plesk. Trying to get symlinks working lead me on a path of frustration ultimately leading to a dead end.

Rails on Plesk

Plesk Onyx takes the pain out of setting up Rails apps. It was in fact almost too easy, and I wasn’t sure if I was missing something. In contrast, setting up my Rails app in CPanel involved delving into manually installing various components via the command line. This ease of use however comes at a price. I quickly discovered that I simply could not get the Rails app installed into a subfolder, and still have the root domain accessible. ie.. sweetpproductions.com. So after many attempts and duckduckgo searches, I decided that my best bet was to…

Run the app on a subdomain!

Simple enough, right. Installing Rails in the root of a domain(or subdomain) is a breeze in Plesk. Just take a look at the tutorial over here. OK nice, but now I need to set up some kind of rewrite so that my app is accessed from sweetpproductions.com/store, and NOT store.sweetpproductions.com.

Apache Alias to the rescue

Let’s add an Alias on the root domain to the subdomain. This will map the requests for sweetpproductions.com/store to store.sweetpproductions.com.

We do this from the Apache & nginx Settings tab.

Scroll to the bottom of the page, and paste the following code into both Additional directives for HTTP and Additional directives for HTTPS

Alias /store /var/www/vhosts/sweetpproductions.com/store.sweetpproductions.com/rails_store/public

So far so good, now we have the site structure we want. But the rails app just won’t load 🙁 We still need to configure a few more things to get it working correctly.

Configure Ruby on the root domain!

This may seem counter intuitive, but this is what we need to do to get our setup working. We won’t actually install the app on the root domain, but we do need a Ruby instance running. Let’s configure Ruby with the same settings as the Ruby install on the subdomain. Take care to make sure that the Ruby version and application mode are identical on the subdomain and root domain.

Now we need to grab some information from the system to enable our app to run correctly. To do this, we need to…

Enable SSH access

This is super easy on Plesk. In the root domain manager, click on FTP Access.

Then on the FTP Accounts tab - add a new user (if you dont have one already) and enable Access to the server over SSH via bin/sh. Now let’s log into the server and get the info we need. We need to configure Ruby on the root domain to load our subdomain hosted rails app with the correct Ruby and Passenger installs. First of all let’s get the location of our Passenger install with the following command:

which passenger-config

taking note of the result:

/usr/bin/passenger-config

We use the output from this command, to find our Ruby location:

/usr/bin/passenger-config -ruby-command
passenger-config was invoked through the following Ruby interpreter:
Command: /opt/plesk/ruby/2.3.1/bin/ruby
Version: ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
To use in Apache: PassengerRuby /opt/plesk/ruby/2.3.1/bin/ruby
To use in Nginx : passenger_ruby /opt/plesk/ruby/2.3.1/bin/ruby
To use with Standalone: /opt/plesk/ruby/2.3.1/bin/ruby /usr/bin/passenger start

The following Ruby interpreter was found first in $PATH:
Command: /var/www/vhosts/sweetpproductions.com/.rbenv/versions/2.3.1/bin/ruby
Version: ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
To use in Apache: PassengerRuby /var/www/vhosts/sweetpproductions.com/.rbenv/versions/2.3.1/bin/ruby
To use in Nginx : passenger_ruby /var/www/vhosts/sweetpproductions.com/.rbenv/versions/2.3.1/bin/ruby
To use with Standalone: /var/www/vhosts/sweetpproductions.com/.rbenv/versions/2.3.1/bin/ruby /usr/bin/passenger start

Configuring Ruby and Passenger

From these two commands, we have now have all the info we need to build our Apache rules.

  • The result from our first command is our PassengerRoot variable.
  • PassengerRuby is found in the output from the second command.
  • In our case we want our store loading at sweetpproductions.com/store, so both PassengerBaseURI and RailsBaseURI will be /store
  • PassengerAppRoot is the root location of our app
  • Directory is the location of the public folder in our app

So now lets re-edit our Apache rules on the root domain to get the rails app working.

Alias /store /var/www/vhosts/mrqwirk.com/store.mrqwirk.com/rails_store/public
PassengerRuby /opt/plesk/ruby/2.3.1/bin/ruby
PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini
RailsEnv development
PassengerEnabled on
<Location /store >
PassengerBaseURI /store
PassengerAppRoot /var/www/vhosts/mrqwirk.com/store.mrqwirk.com/rails_store
</Location><br /> <Directory /var/www/vhosts/mrqwirk.com/store.mrqwirk.com/rails_store/public>
RailsBaseURI /store
AllowOverride all
Options -MultiViews
</Directory>

Success! now our store is loading just fine when we navigate to sweetpproductions.com/store 🙂

We have just one final touch for completion, we need to…

Redirect requests from the subdomain to the root domain

To do this we open up the subdomain in Plesk and add the following code into Additional directives for HTTP and Additional directives for HTTPS on the Apache & nginx Settings tab.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.sweetpproductions\.com<br /> RewriteRule ^(.*)$ http://sweetpproductions.com/%1 [L,NC,QSA]

Edited 17 Oct 2017

Using the previous rewrite rule created an issue with updating the Let’s Encrypt SSL/TLS Certificate. The new rewrite rule below, adds an exception for the .well-known/acme-challenge/ folder, so that Let’s Encrypt can correctly validate:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)\.sweetpproductions\.com<br /> RewriteCond %{REQUEST_FILENAME} !\/\.well-known\/acme-challenge\/<br /> RewriteRule ^(.*)$ http://sweetpproductions.com/%1 [L,NC,QSA]

Done!

Now when anyone visit’s our site at sweetpproductions.com/store they will be shown our rails store. And also if anyone tries to visit store.sweetpproductions.com they will be redirected to our preferred loction at sweetpproductions.com/store.

Posted originally posted Aug 19, 2017 - updated Oct 17, 2017