0

I'm using nginx as a reverse proxy for my web application with proxy_pass for the api. This is my current config, where I've nginx directive location /data/ where images are being displayed from the /data directory of my docker container.

location /data/ {
    alias /data/;
    error_page 404 = @api;
    recursive_error_pages on;
    log_not_found off;
    autoindex off;
    include cache.conf;
}

location /api/ {
    error_page 418 = @api;
    return 418;
}

location @api {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    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 X-NginX-Proxy true;
    proxy_buffering off;
    proxy_request_buffering off;

    proxy_http_version 1.1;
    proxy_pass http://api:1338;
    proxy_cache_bypass $http_upgrade;
}

How to add fallback location to the same named location nginx directive /data/ where I need to add public s3 bucket's url in proxy_pass and at first tries to search for that image inside that s3 bucket using proxy_pass, if found then serves that image from there, if returns 403 or 404 then use alias directive /data/ where it will serve that image from the /data directory of container.

I've tried with this config file, but it fails the nginx config rules check when I validate the nginx configuration using nginx -t command, and shows error nginx: [emerg] the "alias" directive cannot be used inside the named location

server {
    location /data/ {
        proxy_pass http://bucket_url;
        error_page 404 500 502 503 504 = @fallback;
    }

    location @fallback {
        alias /data/;
    }
}
Shyam
  • 1
  • 1
  • Are those `/data/` from `location /data/ { ... }` and `alias /data/` two equal strings? Or those are different? – Ivan Shatsky Jun 20 '22 at 14:10
  • Yes those are two equal strings, the url would be like http://localhost/data/images/1.jpg, if image is found from the s3 bucket url proxy_pass it will show the image from there, if returns 403 or 404, then it will use `alias /data/` as a fallback where it will search for that same image inside the `/data/` directory on the host. – Shyam Jun 20 '22 at 14:24

1 Answers1

0

If your /data/ strings from location /data/ { ... } and alias /data/ are equal, you can use root directive in the named location:

location @fallback {
    root /;
}

If those string are different, lets say /data1/ and /data2/, the following workaround is possible:

location @fallback {
    root /;
    rewrite ^/data1(/.*) /data2$1 break;
}
Ivan Shatsky
  • 2,726
  • 2
  • 7
  • 19
  • Adding root to the fallback location directive is not working, it picks the global root path and prepends that path while opening any image using open(), so my global root path is `/app` and I added root `/` inside the fallback location directive, then nginx opens image with `/app/data/images/1.jpg` and returns 404 instead of `/data/images/1.jpg`. – Shyam Jun 21 '22 at 07:48
  • My nginx doesn't behave like that. I checked this solution explicitly before posting it as an answer. `root` directive setting, being specified explicitly, should overwrite whatever can be inherited from the previous configuration level. What nginx version are you using? – Ivan Shatsky Jun 21 '22 at 07:57
  • Yes you're right, I've checked other blogs regarding this, but mine is somehow prepending the global root path, I'm using nginx with version 1.16.1. – Shyam Jun 21 '22 at 08:37
  • Mine is 1.21.4. Maybe I'd try this with 1.16 somewhat later. Can't tell anything more right now. – Ivan Shatsky Jun 21 '22 at 08:40
  • That's fine, thanks for the help. – Shyam Jun 22 '22 at 05:33