Home > Enterprise >  nginx location block not returning static content
nginx location block not returning static content

Time:10-05

I am attempting to work on a personal project that is using nginx as a reverse proxy, the basic premise of the project is that any static content should always be served up to the user, and any api requests must be authenticated. Any that fail authentication will immediately force the page to redirect to a /login page. I have sucessfully implemented the bulk of the project: auth_request is enabled and working, the content is served up and works fine.

My problem is that I can't seem to be able to handle serving up content from the /login location on a failed api request; I have reduced the problem down to some repeatable code below:

server {
    listen 81;

    location /login {
        root /etc/nginx/websites/login;
        index index.html;
    }
}

Some notes about my configuration:

  • I am running a windows machine and using linux docker containers
  • The port 81 above is mapped to port 80 on my local machine - I'd rather not change this.
  • The path /etc/nginx/websites/login; maps to a folder on my local machine which contains a built Vue3 projects distribution folder. It contains an index.html file, along with other js/ and css/ distributables.
    • I have verified this by browsing to the same location within the container and making sure at least the same files exist.
  • It probably goes without saying, but I'll say it anyway: between each configuration file change, I am running nginx -s reload and in every case below there have been no errors returned.

I would expect that when I browse to localhost/login, the request would be mapped through the location block and load the /login/index.html page. With the code above, on chrome, I get 404 not found.

I have also tried:

server {
    listen 81;

    location /login/ {
        root /etc/nginx/websites/login;
        index index.html;
    }
}

and get the same error.

If I modify the root to:

root /etc/nginx/websites/login/;

The problem persists.

If I try:

server {
    listen 81;

    location /login {
        return 200 'It's heeeere';
    }
}

Then chrome downloads a file containing the above text.

If I try alias, then the entire request is redirected to localhost:81/login and completely falls over - as one would expect.

I can't help but feel I'm missing something entirely obvious, but after 15 hours straight even if the answer jumped out of the page and slapped me in the face I'd probably be oblivious to it!

Configuration blindness aside, and to avoid any "RTFM" responses, I have been through this page in the docs: https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/, as I understand them at least one of the configurations I have posted above should work.

I appreciate any help that you can give in helping me out of this pit of configuration hell. Many thanks,

Steve

EDIT Since the original post, I have checkout out the logs from docker (I also have logs written from nginx and would expect them to be similar, but in this case clearly aren't), and when accessing the endpoint it reports: open() "/etc/nginx/websites/login/login" failed (2: No such file or directory).

This confuses me, I would expect the index.html page would be the default index page, and my explicit declaration should ensure that it is.

Another Edit It seems I was being more of a fool than I anticipated, I took another look at the configuration and realised that the second /login wasn't a file, but a folder. So changed the root directive to:

root /etc/nginx/websites/;

And whilst it no longer throws a 404, it does not return a 301 to localhost:81/login, which - as I stated before - is not a valid endpoint on my local machine.

CodePudding user response:

So the URI /login should return /login/index.html?

The index directive only works with URIs that end with /, which is why you get a redirection to localhost:81.

How do you want to fix this?

If you change your original URI to /login/ the problem goes away.

Otherwise use try_files $uri /login/index.html =404; to force Nginx to return the index file without a redirection.

Other considerations: use port_in_redirect off; and/or server_name_in_redirect off; to achieve a redirection that works for your implementation.

  • Related