I am setting up a Rails 6 Application using Nginx Web server and Puma Application Server.
I want the Nginx web server to serve static web files while the Puma Application server will handle dynamic requests.
I have setup Nginx and here's my Nginx configuration file for the Rails 6 application:
upstream railsserver {
server 127.0.0.1:3000;
}
server {
# Replace 'localhost' with your FQDN if you want to use
# your app from remote or if you need to add a certificate
server_name localhost;
root /home/deploy/my-website/public;
# Define where Nginx should write its logs
access_log /var/log/nginx/my-website/access.log;
error_log /var/log/nginx/my-website/error.log;
location / {
try_files $uri $uri/ @railsserver;
}
location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico) {
expires max;
}
location @railsserver {
proxy_set_header Host $http_host;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300;
proxy_pass http://railsserver;
gzip on;
gzip_types text/plain text/xml text/css image/svg+xml application/javas$
gzip_proxied any;
}
}
I have also restarted Nginx using the command:
sudo systemctl restart nginx
But each time I try to access the website via a browser, I get the error:
404 page not found
I can't seem to figure out where the error is from.
I finally figured it out. The issue was from the Nginx configuration file:
Here's how I solved it:
Modify this directive:
try_files $uri $uri/ @railsserver;
to this
try_files $uri @railsserver;
That is remove $uri/
from the line.
Since we aren't going to be serving any index files (index.html
) directly, there is no need for it to be present. It causes nginx to try to load the files specified in the index directive, or if none exist, to do a directory index.
And since no index file exists or no index directive exists in our Nginx configuration file due to the Nginx configuration is for a dynamic web application, Nginx returns the error 404 page not found
.
So our configuration will look like this:
upstream railsserver {
server 127.0.0.1:3000;
}
server {
# Replace 'localhost' with your FQDN if you want to use
# your app from remote or if you need to add a certificate
server_name localhost;
root /home/deploy/my-website/public;
# Define where Nginx should write its logs
access_log /var/log/nginx/my-website/access.log;
error_log /var/log/nginx/my-website/error.log;
location / {
# First attempt to serve file(s) specified in the index directive,
# then the rails application directory
try_files $uri @railsserver;
}
location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico) {
expires max;
}
location @railsserver {
proxy_set_header Host $http_host;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300;
proxy_pass http://railsserver;
gzip on;
gzip_types text/plain text/xml text/css image/svg+xml application/javas$
gzip_proxied any;
}
}
Next, restart Nginx using the command:
sudo systemctl restart nginx
You can check your website now via your browser, everything should be fine now.
Resources: Does Nginx require an index file for the root directory?
That's all
I hope this helps