Nginx location block – only match actual files

calumbrodie asked:

I have the following nginx config:

server {
    listen 8080;

    root /site_root/web;
    index index.html;

    server_name www.mysite.com;

    location / {
        try_files $uri @rewriteapp;
    }

    location @rewriteapp {
        rewrite ^(.*)$ /app.php/$1 last;
    }

    # add headers to static files
    location ~* .(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
        expires 365d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location ~ .php {
        fastcgi_split_path_info ^(.+.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS $https;
        fastcgi_pass unix:/var/run/php-fpm-www.sock;
    }
}

Issue
This is a standard php application with front controller and some static assets (js/css etc) sitting as files on the filesystem (for arguments sake the location of these files is ‘/site_root/web/assets’).

The intention of the above config is to add ‘max-age’ headers to these static files to allow browsers to cache them. This works for all files which exist on the filesystem. However I have some assets which are dynamically generated and need to pass through php (‘/site_root/web/assets/dynamic/file.uk.js’, ‘/site_root/web/assets/dynamic/file.us.js’, ‘/site_root/web/assets/variable/variable.uk.js’).

The issue is that the inclusion of the location directive ‘add headers to static files’ is causing those dynamic files to 404. How can I either (in order of how desirable each solution is):

  • Change the location directive to exclude files which don’t exist on the server (using try_files/internal?)

  • Change the location directive to exclude paths which match (a whitelist e.g ‘dynamic|variable’)

My answer:


Why don’t you just pass them on to your application?

location ~* .(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
    try_files $uri @rewriteapp;
    #...everything else

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.