Docker部署Nginx托管单页应用SPA刷新子路由返回404
Nginx托管SPA刷新子路由返回404解决方案
核心根因
- 当前配置存在两个同端口的冲突server块:官方Nginx镜像默认会加载
/etc/nginx/conf.d/*.conf路径下的所有配置,该目录内置的default.conf自带一个监听80端口的默认server块 - 你在主
nginx.conf的http块中额外手写了一个同样监听80端口的自定义server块,由于未指定明确的server_name,Nginx会优先匹配配置加载顺序靠前的默认server块,你的自定义try_files回退规则完全没有生效 - 当请求不存在的静态文件路径(如
/en)时,默认server块没有配置SPA回退逻辑,直接返回404
解决方案
方案1:直接在主配置中禁用默认配置加载
找到主nginx.conf中http块内的include /etc/nginx/conf.d/*.conf;语句,注释或删除该行,避免加载内置的冲突配置,让自定义server块成为唯一的80端口处理规则:
http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; # 注释该行,不再加载conf.d目录下的默认配置 # include /etc/nginx/conf.d/*.conf; server { listen 80; root /usr/share/nginx/html; gzip on; gzip_types text/css application/javascript application/json image/svg+xml; gzip_comp_level 9; etag on; location / { try_files $uri $uri/ /index.html; } # 其余原有location配置保持不变 } }
方案2:替换默认配置文件(推荐)
更符合Nginx配置规范的做法是不直接修改主nginx.conf的结构,而是将自定义的server配置单独提取,直接替换掉内置的default.conf:
- 将你手写的完整server块内容保存为本地独立文件
nginx-spa.conf - 修改Docker启动命令,不再挂载主
nginx.conf,改为直接挂载自定义配置替换默认配置文件:
docker run --name spa \ -v "$PWD/build":/usr/share/nginx/html:ro \ -v "$PWD/nginx-spa.conf":/etc/nginx/conf.d/default.conf:ro -d -p 8080:80 nginx
该方式可最大程度保留官方主配置的默认参数,避免后续Nginx版本升级带来的配置兼容问题。
生效验证
- 执行
docker exec spa nginx -T查看容器内完整加载的配置,确认输出中存在你的try_files $uri $uri/ /index.html规则 - 执行
curl -I http://localhost:8080/en测试子路由请求,返回200状态码即表示配置正常,404问题解决
内容的提问来源于stack exchange,提问作者HMR
相关产品推荐
相关产品推荐

