Nginx location to find images in the root directory

nginx

I inherited a web project from a client who threw a bunch of images and PDF files in the root directory of their site so they could easily send links to those images/files to their clients.

Moving the site to a new server, so the links set previously still need to work, but I'd love to clean this up a bit. There are hundreds of these files just loose in the root.

Ideally, I'd like to move all of the loose images/files to a directory (let's call it "stuff" for now) and then write an Nginx directive to redirect.

Something like this:

location = / {
    location ~* \.(gif|jpg|jpeg|pdf)$ {
        rewrite ^(.*) https://example.com/stuff/$1 last;
    }
}

but obviously Nginx won't allow a nested location block inside an exact match block.

Is it possible to find ONLY certain file types (by extension) but ONLY in the root directory?

Forgive me if this is obvious. This is a bit outside my wheelhouse. Any help would be greatly appreciated.

Best Answer

Your two location blocks are in direct conflict. location = / matches only requests for the https://www.example.com/ URL, nothing else. This means that no request matching the nested location directive never enters the block.

However, the following approach should work:

location ~* ^/[^/]+\.(?:gif|jpg|jpeg|pdf)$ {
    root /var/www/stuff;
    try_files $uri =404;
}

One does not need nested locations here.

What this configuration means is that for the files with particular extensions in root directory, we set the root directory for serving the files to /var/www/stuff, and then we try to send the file using try_files. If file is not found, 404 error is sent.

The ?: in the regular expression match is optional, it is simply a slight optimisation telling nginx not to capture the value inside parentheses to a local variable.