I have an Nginx configuration where I am proxying requests to an external resource (an s3 service), but when trying to access a specific static file, Nginx falls back to the try_files directive instead of proxying the request. Here is the simplified configuration:
server {
listen 443 ssl;
server_name test.lightningmoment;
location /static/ {
proxy_pass .haiskynology.lightningmoment.web/test/build/static/;
proxy_set_header Host test-cdn.lightningmoment;
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;
}
location / {
proxy_pass .haiskynology.lightningmoment.web/test/build/;
proxy_set_header Host test-cdn.lightningmoment;
try_files $uri $uri/ /index.html;
}
}
The file logo64.png
exists at the following OSS path, :
.haiskynology.lightningmoment.web/test/build/logo64.png.
When I try to access .png, it results in Nginx falling back to the try_files logic and serves the index.html file instead of proxying the request to the OSS server.
I confirmed that the file exists and can be accessed directly using a manual proxy configuration like this:
location /logo64.png {
proxy_pass .haiskynology.lightningmoment.web/test/build/logo64.png;
proxy_set_header Host test-cdn.lightningmoment;
}
Samely, I also cannot access files under the static folder unless I explicitly add the location /static/
configuration.
My questions: Why is the request to /logo64.png falling back to try_files?
How can I fix the proxy_pass to correctly forward requests without falling into the try_files fallback logic?
What debugging steps can I take to diagnose this further?
I am expecting users to access the React website test.lightningmoment
with nginx as the first layer of entrance, and then I want to add a cdn to it.
Thanks in advance!
I have an Nginx configuration where I am proxying requests to an external resource (an s3 service), but when trying to access a specific static file, Nginx falls back to the try_files directive instead of proxying the request. Here is the simplified configuration:
server {
listen 443 ssl;
server_name test.lightningmoment.com;
location /static/ {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/static/;
proxy_set_header Host test-cdn.lightningmoment.com;
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;
}
location / {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/;
proxy_set_header Host test-cdn.lightningmoment.com;
try_files $uri $uri/ /index.html;
}
}
The file logo64.png
exists at the following OSS path, :
https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/logo64.png.
When I try to access https://test.lightningmoment.com/logo64.png, it results in Nginx falling back to the try_files logic and serves the index.html file instead of proxying the request to the OSS server.
I confirmed that the file exists and can be accessed directly using a manual proxy configuration like this:
location /logo64.png {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/logo64.png;
proxy_set_header Host test-cdn.lightningmoment.com;
}
Samely, I also cannot access files under the static folder unless I explicitly add the location /static/
configuration.
My questions: Why is the request to /logo64.png falling back to try_files?
How can I fix the proxy_pass to correctly forward requests without falling into the try_files fallback logic?
What debugging steps can I take to diagnose this further?
I am expecting users to access the React website test.lightningmoment.com
with nginx as the first layer of entrance, and then I want to add a cdn to it.
Thanks in advance!
Share Improve this question asked 2 days ago Seaky LoneSeaky Lone 1,0373 gold badges17 silver badges37 bronze badges 1 |1 Answer
Reset to default 0Did you read the try_files
directive documentation at all? Using try_files
with the proxy_pass
directive is completely meaningless. Why should you proxy the request to some other backend if the requested file is available locally?
Every request ends up in a particular location, and every location has one and only one content handler. Unless the content handler is specified explicitly via one of the ..._pass
directives (proxy_pass
, fastcgi_pass
, uwsgi_pass
, etc), the default static content handler is used implicitly.
That is, if you specify the proxy_pass
content handler for the root location, the static content handler will never be used.
What you probably want to achieve is to serve the request for the static file locally, and proxy the request to CDN if the file isn't found locally. This can be done using the following configuration:
location / {
try_files $uri /index.html;
}
location /static/ {
try_files $uri @cdn_fallback;
}
location @cdn_fallback {
rewrite ^ /com.haiskynology.lightningmoment.web/test/build$uri break;
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com;
proxy_set_header Host test-cdn.lightningmoment.com;
}
(we can't use a URI part in the proxy_pass
directive within the named location, so I change the upstream request URI using the rewrite ... break
directive.)
Or, to mix this with a React Router:
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
rewrite ^ /com.haiskynology.lightningmoment.web/test/build$uri break;
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com;
proxy_set_header Host test-cdn.lightningmoment.com;
proxy_intercept_errors on;
error_page 404 = /index.html;
}
(here, we intercept the 404 Not Found
HTTP error from the CDN upstream and use the /index.html
URI as a fallback, assuming the request URI is a React route rather than a static file name.)
However, I wouldn't call this a brilliant approach, since every page refresh, when the current route is different from root, will lead to an extra proxy_pass
call to your CDN.
What exactly you are trying to achieve? Do you have any static files in some folder(s) other than /static/
?
P.S. Different try_files
directives (try_files $uri ...
vs try_files $uri $uri/ ...
) in the examples above are used on purpose.
Update according to OP comments
If you are planning to to put all the frontend files onto the S3 server, the following more simple configuration should work:
location / {
proxy_pass https://haiskynology-test-web.oss-cn-hangzhou.aliyuncs.com/com.haiskynology.lightningmoment.web/test/build/;
proxy_set_header Host test-cdn.lightningmoment.com;
proxy_intercept_errors on;
error_page 404 = /index.html;
}
/
location block includes thetry_files $uri $uri/ /index.html;
directive. When you request/logo64.png
, Nginx first checks for a local file, and since it doesn't exist, it falls back to serving/index.html
. This behavior is common in SPAs like React. – Shakya Dissanayake Commented 2 days ago