You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx反向代理Docker容器时site2静态资源404的解决方法

解决Nginx反向代理中site2静态资源404的问题

我完全懂你的困扰——想保留静态资源的缓存、日志优化规则,但site2的静态资源一直返回404。问题出在你当前的静态资源location块逻辑里:当请求/site2/css/style.css这类资源时,你通过if判断把请求转发到production-site2,但没有去掉/site2这个前缀,导致site2容器收到的请求路径是/site2/css/style.css,而容器内的资源实际是放在/css/style.css(对应容器根路径),自然找不到资源返回404。

下面是修正后的配置,既能保留静态资源的优化规则,又能正确路由site2的静态资源:

server {
 listen 80 default_server;
 server_name _;

 location ~ /\. {
 deny all;
 }

 # 优先匹配site2的静态资源,捕获/site2后的路径转发给容器
 location ~* ^/site2/(.+\.(?: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))$ {
 proxy_pass http://production-site2/$1;
 expires 7d;
 access_log off;
 }

 # site2的svg、字体资源处理
 location ~* ^/site2/(.+\.(?:svgz?|ttf|ttc|otf|eot|woff|woff2))$ {
 proxy_pass http://production-site2/$1;
 add_header Access-Control-Allow-Origin "*";
 expires 7d;
 access_log off;
 }

 # 主站的静态资源规则
 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)$ {
 proxy_pass http://production-site1;
 expires 7d;
 access_log off;
 }

 # 主站的svg、字体资源规则
 location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff|woff2)$ {
 proxy_pass http://production-site1;
 add_header Access-Control-Allow-Origin "*";
 expires 7d;
 access_log off;
 }

 gzip on;
 gzip_comp_level 2;
 gzip_http_version 1.0;
 gzip_proxied any;
 gzip_min_length 256;
 gzip_buffers 16 8k;
 gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
 gzip_disable "MSIE [1-6]\.(?!.*SV1)";
 gzip_vary on;

 location / {
 proxy_pass http://production-site1/;
 proxy_http_version 1.1;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }

 location /site2 {
 proxy_pass http://production-site2/;
 proxy_http_version 1.1;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }
}

关键修改说明:

  • 把site2的静态资源规则单独拆分,用^/site2/(.+)正则捕获/site2之后的资源路径,再通过proxy_pass http://production-site2/$1把去掉前缀后的路径传给容器,这样容器就能匹配到正确的资源路径了。
  • 利用Nginx的location匹配优先级(更具体的正则会先被匹配),避免了之前用if带来的意外行为(Nginx的if在很多场景下会有逻辑陷阱,尽量少用)。

如果你觉得重复写两次静态资源后缀太冗余,也可以用map简化配置:

# 提前定义静态资源对应的后端和路径
map $request_uri $static_backend {
 ~^/site2/ http://production-site2;
 default http://production-site1;
}

map $request_uri $static_path {
 ~^/site2/(.+) $1;
 default $request_uri;
}

server {
 # ... 其他配置不变

 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)$ {
 proxy_pass $static_backend/$static_path;
 expires 7d;
 access_log off;
 }

 location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff|woff2)$ {
 proxy_pass $static_backend/$static_path;
 add_header Access-Control-Allow-Origin "*";
 expires 7d;
 access_log off;
 }

 # ... 其他配置不变
}

这种方式用map提前定义好后端地址和处理后的路径,让配置更简洁,核心原理和上面一致——都是去掉site2的前缀后转发请求。

测试时可以用curl -I http://example.com/site2/css/style.css查看响应头,确认是否返回200,也可以查看Nginx日志验证请求是否正确转发到site2容器的对应路径。

内容的提问来源于stack exchange,提问作者Pedro Alves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:18:53