Nginx index not at project root

Chris asked:

I have an index.html page that’s stored alongside with the rest of my client-side resources (/opt/django/media/index.html). I can get nginx to serve the page as the index for requests to just the domain name, however it serves it as if it is located in the project root not in the media directory. This means that things like my images that used to be accessible in the page at images/123.png now have to go through media/images/123.png in my index.html. Should I just update the resource paths in my page or is there a better way of doing this? My configuration follows:

server {
    listen   80;
    server_name localhost;

    access_log /opt/django/logs/nginx/vc_access.log;
    error_log  /opt/django/logs/nginx/vc_error.log;

    # no security problem here, since / is alway passed to upstream
    root /opt/django/;
    location = / {
        index media/index.html;
    }
    # serve directly - analogous for static/staticfiles
    location /media/ {
        # if asset versioning is used
        if ($query_string) {
            expires max;
        }
    }
    location /static/ {
        # if asset versioning is used
        if ($query_string) {
            expires max;
        }
    }
    location /metro/ {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 10;
        proxy_pass http://localhost:8080/;
    }
    location / {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 10;
        proxy_pass http://localhost:8000/;
    }
    # what to serve if upstream is not available or crashes
    error_page 500 502 503 504 /media/50x.html;
}

My answer:


This is a job for try_files.

Something like this should get you started:

server {
    # ...

    root /opt/django;

    location @django {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 10;
        proxy_pass http://localhost:8000/;
    }
    # what to serve if upstream is not available or crashes
    error_page 500 502 503 504 /media/50x.html;

    location / {
        try_files /media$uri $uri $uri/ @django;
    }
}

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.