Search code examples
nginxghost-blog

Static images not able to redirect


I have an NGINX server which I use to provide reverse proxy services to two Ghost blogging sites. For static content I would like to have it skip over the node services and be served directly by NGINX. Should be pretty straight forward but there's a twist.

Here's a config block that sets up the reverse proxy and then provides an exception for static content. This works fine (note: the double bracketed references are replaced with the names of the two different Ghost services I'm using):

location / {
    proxy_redirect off;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto   $scheme;
    proxy_set_header    Host                $http_host:$server_port;
    proxy_set_header    X-NginX-Proxy       true;
    proxy_set_header    Connection          "";
    proxy_http_version  1.1;
    proxy_cache         ghost_{{slug}}_cache;
    proxy_cache_key     ghost$request_uri$scheme;
    proxy_pass          http://ghost_{{slug}}_upstream;
}

location /assets {
    root                {{assets_root}};    
}

So in the case of /assets a request like http://example.com/assets/js/doit.js and the above configuration would match on /assets and then append "assets/js/doit.js" to the root direct defined above. As I said this part WORKS and it works because the location I'm pointing to has the full URL path represented in the file system (e.g., there is a directory assets/js with a file doit.js in it).

What I'm struggling with -- and I'm very new to NGINX so suspect this is easy -- is the similar situation where you have a configuration block like this:

location /content {
    root                {{content_root}};
}

This block -- from a configuration and execution standpoint -- is identical to the assets block but in this case what I want to happen is I want it to pass along only the part of the URL that follows content. So if the request is http://example.com/content/images/july/foo.jpg then what's returns is whatever resides on the filesystem at:

  • {{content_root}} + /images/july/foo.jpg

instead of what I'm getting right now which is:

  • {{content_root}} + content + /images/july/foo.jpg

Solution

  • Ok, I've figured out an answer to my question ... assuming a URL GET request of http://example.com/content/js/foobar.js:

    • The original location directive of:

      location /content {
          root                /var/www/content;
      }
      

      Would mistakenly look for the javascript file in the "/var/www/content/content" directory

    • Instead using the following location directive:

      location /(content)/ {
          root                /var/www/content;
      }
      

      This would correctly look for the file in the "/var/www/content" directory.

    Happy days.