digitalocean / nginxconfig.io

⚙️ NGINX config generator on steroids 💉
https://do.co/nginxconfig
MIT License
27.66k stars 2.04k forks source link

Not able to proxy requests for assets, media files #412

Open doggy8088 opened 1 year ago

doggy8088 commented 1 year ago

Information

https://whatismybrowser.com/w/MLNCGRF

Details

# reverse proxy
location / {
    proxy_pass            http://127.0.0.1:3000;
    proxy_set_header Host $host;
    include               nginxconfig.io/proxy.conf;
}

Description

Wrong:

# reverse proxy
location / {
    proxy_pass            http://127.0.0.1:3000;
    proxy_set_header Host $host;
    include               nginxconfig.io/proxy.conf;
}

Correct:

# reverse proxy
location ^~ / {
    proxy_pass            http://127.0.0.1:3000;
    proxy_set_header Host $host;
    include               nginxconfig.io/proxy.conf;
}

Steps to reproduce

Open this link

Expected behavior

I expected to have ^~ after location directive.

# reverse proxy
location ^~ / {
    proxy_pass            http://127.0.0.1:3000;
    proxy_set_header Host $host;
    include               nginxconfig.io/proxy.conf;
}

See also: https://nginx.org/en/docs/http/ngx_http_core_module.html#location

In versions from 0.7.1 to 0.8.41, if a request matched the prefix location without the "=" and "^~" modifiers, the search also terminated and regular expressions were not checked.

Screenshots

image

MattIPv4 commented 1 year ago

When you say the syntax is "wrong", how does the routing behaviour break/change? Can you give an example of requests that are being routed incorrectly as a result of this?

doggy8088 commented 1 year ago

Here is my use case:

  1. I have a internal site: http://127.0.0.1:3000
  2. I need a reverse proxy that route ALL traffic through NGINX (I run under Docker.)

I tested. When using location /, only the / been routed in NGINX 1.23.2. The /style.css won't route, it will get 404 not found.

Here is my server config, there is only one location directive.

server {
    listen              443 ssl http2;
    listen              [::]:443 ssl http2;
    server_name         mysite;
    root                /usr/share/nginx/html/public;

    # SSL
    ssl_certificate     /etc/nginx/ssl/mysite.pem;
    ssl_certificate_key /etc/nginx/ssl/mysite-key.pem;

    # security
    include             nginxconfig.io/security.conf;

    # logging
    access_log          /var/log/nginx/access.log combined buffer=512k flush=1m;
    error_log           /var/log/nginx/error.log error;

    # reverse proxy
    location ^~ / {
        resolver 127.0.0.11;
        set $upstream_host my-app;
        proxy_pass            http://$upstream_host:50050;
        proxy_set_header Host $host;
        include               nginxconfig.io/proxy.conf;
    }

    # additional config
    include nginxconfig.io/general.conf;
}
MattIPv4 commented 1 year ago

Ah I see, because nginxconfig.io/general.conf contains a regex location block for CSS files.

MattIPv4 commented 1 year ago

Hm, I'm not sure updating the proxy location to be ^~ / is the best idea here then, as it'd break the settings under nginxconfig.io/general.conf for asset expiration etc.

I wonder if there's a better way to apply those expirations while still allowing the proxy to work to catch all requests.

doggy8088 commented 1 year ago

Oh, I just realized that I have a few location directives in the general.conf.

I see this in the doc:

Among them, the location with the longest matching prefix is selected and remembered.

That's why location / unable to proxy *.css files.

I can only find a way to proxy those asset files:

# reverse proxy
location / {
    resolver 127.0.0.11;
    set $upstream_host my-app;
    proxy_pass            http://$upstream_host:50050;
    proxy_set_header Host $host;
    include               nginxconfig.io/proxy.conf;
}

# assets, media
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {

    resolver 127.0.0.11;
    set $upstream_host my-app;
    proxy_pass            http://$upstream_host:50050;
    proxy_set_header Host $host;
    include               nginxconfig.io/proxy.conf;

    expires 7d;
}

But I don't know what NGINXCONFIG can do in the existing preset. I think you might be able to add a new Reverse Proxy Presets for this.

doggy8088 commented 1 year ago

I made a prototype for this context. (Route all requests)

image

If you check this option, the location / { will become location ^~ / {.

doggy8088 commented 1 year ago

hack way. not recommended.

image

doggy8088 commented 1 year ago

@MattIPv4 Maybe turn off expires settings when enable Reverse proxy is a good choice?

MattIPv4 commented 1 year ago

I don't think disabling it would be the right move, as other domains in the tool might still be using it without a reverse proxy.

I think the best move would be to add a warning to the expires section in the tool when any domain is using the reverse proxy -- we show warnings in a few other places in the tool so I think it makes sense to lean into a standard UI/UX convention here.

With that warning in place, I'm fine with then switching the proxy block to using ^~, as I believe this was probably the intended behaviour all along. As that's then a regex operator, I believe it'll take precedence over the expiration blocks further down in the config, 'cause the logic for regex blocks is just the first matching block in the config?