Can't serve static files on my droplet running Ghost with Nginx, keep getting 404 error

October 9, 2018 1.1k views
Ghost Nginx Ubuntu 18.04

I have a droplet running Ghost on Ubuntu 18.04 with Nginx. I’m trying to set up a way to serve static assets for my website, Javascript files, images, stuff like that. I’ve followed a few guides and no matter what I keep getting a 404 error when I try to access any files.

This is my Nginx configuration which is at /etc/nginx/sites-enabled/www.james-warren.com.conf

# HTTP server (non-www) -- redirect to https://James-warren.com
server {
    listen 80;
    server_name James-warren.com;
    return 301 https://www.James-warren.com$request_uri;
}

# HTTP server (www) -- redirect to https://James-warren.com
server {
    listen 80;
    server_name www.James-warren.com
    return 301 https://www.James-warren.com$request_uri;
}

# HTTPS server (www) -- redirect to https://James-warren.com -- Add HSTS header
server {
    listen 443 ssl;
    server_name www.James-warren.com;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    return 301 https://www.James-warren.com$request_uri;
}

server {
    listen 80;
    listen [::]:80;

    server_name www.james-warren.com;
    root /var/www/ghost/system/nginx-root;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;

    }
    # For serving static files
    location /static/ {
        root /var/www/static/;
    }

    location ~ /.well-known {
        allow all;
     }


    client_max_body_size 50m;
}

This is what my file structure looks like:
https://i.imgur.com/khVc8ER.png

1 Answer
X40C October 9, 2018
Accepted Answer

Did you try hosting your static files where you initially installed ghost as nginx only acts as a proxy for ghost at the moment and i’m not sure if the location parameter has any effect at all.

  • I just tried that now, still quite new to all this kind of stuff. I tried putting a static folder in a couple of places since I wasn’t sure where to put it, I tried putting it in the following places:

    /var/www/ghost/static
    /var/www/ghost/system/nginx-root/static
    /var/www/ghost/system/static

    None of them worked, was this what you meant or am I misinterpreting it?

    • Heya,

      So what i did is create one of those one`click Ghost apps VM, logged in, completed the install and made the bellow changes to the /etc/nginx/sites-available/165.227.154.*.conf .

      root@ghost-s-1vcpu-1gb-fra1-01:/etc/nginx/sites-available# cat 165.227.154.*.conf
      server {
          listen 80;
          listen [::]:80;
      
          server_name 165.227.154.*;
          root /var/www/ghost/system/nginx-root;
      
          location / {
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header Host $http_host;
              proxy_pass http://127.0.0.1:2368;
      
          }
      location /static/ {
          alias /var/www/static/;
      }
          location ~ /.well-known {
              allow all;
          }
      
          client_max_body_size 50m;
      }
      
      

      Afterwards i restarted nginx with service nginx restart and then changed dir to the ghost install directory with cd /var/www/ghost and restarted ghost with ghost restart.
      I have created a /static/ directory in /var/www/ with a simple .htm file in it after that and i could access it via the http://ip/static/file.htm.

      Regards,
      Alex

      • First off, thank you so much, Alex, you’re a legend. I still can’t quite get it to work though.

        I followed what you did as closely as possible and there’s a bit of progress, I can now access the static files if I use the IP address of the server instead of the domain name. I can go to ip/static/test.txt I get the asset but through htttp://www.james-warren.com/static/test.txt/ I still get a 404 error. I’ve tried clearing cache, incognito mode and a different browser as well.

        Not sure if it’s relevant but when I use the domain name I get a trailing slash put on the end. Like I type in https://www.james-warren.com/static/test.txt and get it changed to https://www.james-warren.com/static/test.txt/ in the address bar.

        • Heya,

          So i added a hostname to my droplet and went ahead with a rebuild with the same ghost image. After set`up i noticed there were 2 config files in /etc/nginx/sites-enabled/ for http and https. Did you edit them both cause that may be the problem. I only get a 404 error if i leave the ssl.conf unchanged in /etc/nginx/sites-enabled/.

          • Now i’m getting an nginx 404 in Chrome after i only restarted nginx and didn’t restart ghost even after i did a reboot of the VM, Tried clearing browsing history and it does nothing. Accessed the same url with Microsoft Edge and it works as expected. After an advanced clean'up of browsing data for the past hour chrome started displaying the page correctly as well.

            You should try rebuilding the droplet and editing the configs and all that, after which you could use a fresh browser or maybe an incognito tab could work(Not sure bout this) to access the static file url.

          • You’ve done it, you’re an absolute lifesaver, that was it. I can’t thank you enough, I’d spent so long trying to get this to work. Thank you Alex

            I’ll just leave these here for anyone else who comes across this question later. This is what my working configuration files look like now:

            /etc/nginx/sites-enabled/www.james-warren.com.conf

            # HTTP server (non-www) -- redirect to https://James-warren.com
            server {
                listen 80;
                server_name James-warren.com;
                return 301 https://www.James-warren.com$request_uri;
            
            }
            
            # HTTP server (www) -- redirect to https://James-warren.com
            server {
                listen 80;
                server_name www.James-warren.com
                return 301 https://www.James-warren.com$request_uri;
            
            }
            
            # HTTPS server (www) -- redirect to https://James-warren.com -- Add HSTS header
            server {
                listen 443 ssl;
                server_name www.James-warren.com;
                add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
                return 301 https://www.James-warren.com$request_uri;
            
            }
            
            server {
                listen 80;
                listen [::]:80;
            
                server_name www.james-warren.com;
                root /var/www/ghost/system/nginx-root;
            
                location / {
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header Host $http_host;
                    proxy_pass http://127.0.0.1:2368;
            
                }
                # For serving static files
                location /static/ {
                    alias /var/www/static/;
                }
            
                location ~ /.well-known {
                    allow all;
                 }
            
            
                client_max_body_size 50m;
            }
            

            /etc/nginx/sites-enabled/www.james-warren.com-ssl.conf

            server {
                listen 443 ssl http2;
                listen [::]:443 ssl http2;
            
                server_name www.james-warren.com;
                root /var/www/ghost/system/nginx-root;
            
                ssl_certificate /etc/letsencrypt/www.james-warren.com/fullchain.cer;
                ssl_certificate_key /etc/letsencrypt/www.james-warren.com/www.james-warren.com.key;
                include /etc/nginx/snippets/ssl-params.conf;
            
                location / {
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto $scheme;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header Host $http_host;
                    proxy_pass http://127.0.0.1:2368;
            
                }
            
                location /static {
                    alias /var/www/static/;
                }
            
                location ~ /.well-known {
                    allow all;
                }
            
                client_max_body_size 50m;
            }
            
Have another answer? Share your knowledge.