Receiving a 404 for a file that exists in nginx web server

I recently switched the web server on my CentOS 7 machine from Apache to nginx. I use software to take screenshots on my computers and to upload them to the server for public viewing. Originally, it worked fine on Apache – however, now I am running into an issue where nginx will serve a 404 error for some of my .png images on the web server.

I referred to this question with a very similar issue, but I couldn't make sense of the solution in the context of my own problem.

I have a snippet of the server block for the image server below.

server {
    listen       80;
    server_name  imageserver.example.com;
    root         /usr/share/nginx/imageserver.example.com/public_html;

    access_log   imageserver.example.com/logs/imageserver.example.com_access.log;
    error_log    imageserver.example.com/logs/imageserver.example.com_error.log crit;

    location / {
        index  index.html index.htm;
    }

    location ~* \.png {
        root       imageserver.example.com/public_html/u/;
        expires    max;
        add_header Pragma public;
        add_header Cache-control "public, must revalidate, proxy-revalidate";
    }
}

An example link is this image. I have confirmed the file exists on the server, and it has the following permissions.

$ lsa 7b724394b851299c68b15f1172f158c6.png -rw-rw-r--. 1 jflory nginx 2.4K Nov 3 11:13 7b724394b851299c68b15f1172f158c6.png

I am very confused about how to fix this. What could the problem be?


The root directive in the location ~* \.png container is adding a /u/ to the end of your URL, so the server is looking in /u/u/ for the image.

This root directive is actually unnecessary, as the value will be inherited from the value defined in your server block.


The image file is in the root dir, not /u/

Remove the /u in your link and you will see the image loads.


Curious though, wouldn't /u/ be the root directory for the images, since that's where they are all stored? I don't know if I quite understand why this fixed it.

You need to give path of public_html directory only. See the following example to understand.

File structure:

.../public_html/

-- /u/myimg.jpg

-- /index.html

Code to show the image in index.html:

<img src="/u/myimg.jpg">

So if you set .../public_html/u/ as your image server path then the server will try to find .../public_html/u/u/myimg.jpg, and so it will throw the 404 error. Hope this helps :)