Rails Server with Apache + Puma (via reverse proxy)

Back in my PHP days, I knew there was 2 main ways to serve a PHP site:

  • Apache + mod_php
  • Apache + FastCGI

* ok, actually is any webserver with FastCGI support on this last one (nginx, lighttpd, cherokee, and so on).

When I started in Rails, I found strange that no one recommends to use FastCGI or a mod_ruby solution. Instead, the community only talks about Phusion Passenger, Puma, and Unicorn. Phusion Passenger is a Apache module, just like mod_php (it is informally known as mod_rails). Passenger is the most recommended and used solution. But personally, at a first glance, I didn’t like Passenger – it’s a proprietary software with free and pay options. I don’t know, I think there’s a conflict of interest in cases like that.

The other 2 options, Puma and Unicorn, are like ruby interpreters with a built-in web server. You call them inside a rails project root folder and they will listen the port 80 (or one of your own), wait for web conections, run the rails code and answer to the browser – without apache, nginx, or any else.

Let’s suppose that you have 2 rails projects (sites) that you want to run simultaneously:

$ cd /var/www/site-1
$ puma -e production -p 9292 -d
$ cd /var/www/site-2
$ puma -e production -p 9293 -d

Now, on your browser, open http://localhost:9292 on a tab and http://localhost:9293 on another tab.

Wow! This is way much more easy than install and configure 3 softwares: apache, mod_php, php. But this also brings some problems: the most serious is “what if you want multiples sites in just one server?”. You can’t start 2 puma/unicorn servers on the same port (80).

I present here a way to use Apache + Puma, so you can have all the Apache conveniences, including the VirtualHosts and modules.

Our recipe:

1. Add puma to your Gemfile:

gem "puma", group: :production

2. Install Puma gem:

$ cd /var/www/site-1
$ bundle install

3. Start your app via puma:

$ cd /var/www/site-1
$ puma -e production -p 9292 -d

PS: you can start more than 1 process (with “-w “), and define the number min and max of threads per process (with “-t :“). This is good if you have more than 1 core processor. Example: “puma -e production -p 9292 -w 2 -t 4:32 -d” – this will start 2 processes and 4 threads per process (that will increase until 32).

4. Install mod_proxy and mod_proxy_http:

$ sudo a2enmod proxy
$ sudo a2enmod proxy_http

5. Edit your domain #1 configuration:

$ sudo nano /etc/sites-available/site-1.conf

  ServerName www.site-1.com
  ServerAlias site-1.com
  DocumentRoot /var/www/site-1/public

    ProxyPass !
    ProxyPass !

  ProxyPass /
  ProxyPassReverse / # don't forget the trailing slashes at end!!!

7. Enable your domain #1 and restart Apache:

$ sudo a2ensite site-1
$ apachectl -t
# Syntax Ok
$ sudo /etc/init.d/apache2 restart

PS: Notice the “ProxyPass” bypassing “assets” and “system”, so they won’t be processed by Ruby.

That’s it. You can add another site using another port (9293, 9294, and so on).

Close Menu