Ghost Assets and Admin Page 404ing with Custom Nginx Config

I’m have a server where I initially set up Nginx with a LetsEncrypt SSL before I installed the Ghost CMS. I went ahead and skipped the step where Ghost prompts you to set up Nginx, and now with the following config, I can get the homepage to work, but the following gives me 404s

  • everything from the /assets dir
  • any other page besides the homepage (admin panel, any subpath under the homepage)

What version of Ghost are you using?

ghost -v
1.11.0

CMS version is 2.31.1

What configuration?

{
  "url": "https://example.com",
  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "localhost",
      "user": "ghost_user",
      "password": "PASSWORD",
      "database": "ghost_db"
    }
  },
  "mail": {
    "transport": "Direct"
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/www/example.com/html/content"
  },
  "bootstrap-socket": {
    "port": 8000,
    "host": "localhost"
  }
}

Nginx Config:

server {

        server_name example.com www.example.com;

        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;
            try_files $uri $uri/ =404;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;
    return 404; # managed by Certbot

What Port

2368

Got this working. Here’s my final Nginx config:

proxy_cache_path /var/run/cache levels=1:2 keys_zone=STATIC:75m inactive=24h max_size=512m;

server {

    server_name example.com www.example.com;
    add_header X-Cache $upstream_cache_status;
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        try_files _ @ghost;
    }

    location /content/images {
      alias /var/www/example.com/html/versions/2.31.1/content;
      access_log off;
      expires max;

      try_files $uri @ghost;
    }

    location /assets {
      alias /var/www/example.com/html/versions/2.31.1/content/themes/casper/assets;
      access_log off;
      expires max;

      try_files $uri @ghost;
    }


    location @ghost {
        proxy_cache STATIC;
        proxy_cache_valid 200 30m;
        proxy_cache_valid 404 1m;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_ignore_headers Set-Cookie;
        proxy_hide_header Set-Cookie;
        proxy_hide_header X-powered-by;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        expires 10m;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://127.0.0.1:2368;
    }
}

server {

    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    return 404; # managed by Certbot
}