Nginx is a popular web server for Rails apps. Typically you’d have one Nginx file per application. However, you may want to run multiple Rails apps on a single server, for rapid prototyping. In this case, you can make do with a single Nginx file.
Here’s an example nginx.conf
file that runs two Rails applications, app1
and app2
. Both apps are using Puma as an app server.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
http {
upstream app1 {
server unix:/var/www/app1/current/tmp/sockets/puma.sock fail_timeout=0;
}
upstream app2 {
server unix:/var/www/app2/current/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name app1.com
root /var/www/app1/current/public;
location / {
proxy_pass http://app1;
}
}
server {
listen 80;
server_name app2.com
root /var/www/app2/current/public;
location / {
proxy_pass http://app2;
}
}
}
Let’s step through each part to understand how it works.
Upstream blocks
upstream
is an Nginx directive used to define servers. In this case, we’re defining two serves: app1
and app2
.
Inside the upstream
block is a server
directive that defines the address of the two app servers. In this case, it’s a UNIX socket connection to a running puma process.
Server blocks
Next, we have two server blocks, one for each app. Both server blocks have the same logic, here’s how they work:
listen
The first line uses the listen
directive to listen on port 80. If you want to run apps over https then you’d need to change listen
to port 443 and define your SSL certs.
server_name
The next line defines server_name
. It’s used by Nginx to look up which server block to run. It does this using the Host
header, sent by the browser.
root
root
specifies the root directory, from which Nginx will search for other relative files. This should point to the Rails root directory.
Location block
Lastly, there is a location block. This block specifies /
which means it matches any URI (given there are no other location blocks defined). It then proxies the request to the upstream server (app1
or app2
) using proxy_pass
. This is how Nginx connects to Puma.
Further improvements
It’s worth noting that, although this setup works, it doesn’t scale well. Managing many applications would be difficult - it would become a single file of spaghetti code. If you intend to scale this up past 2-3 sites, we recommend creating separate config files in sites-available
.