Search code examples
ruby-on-railsnginxpuma

Rails: 404 page not found using Nginx Web Server


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.


Solution

  • 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