CSS在Docker容器中404,90%是因为前端构建时相对路径(如url(../fonts/icon.woff))与容器内真实文件结构不匹配,必须同步调整Vite/Webpack的base/publicPath配置和Nginx的location+root规则,三者对齐才有效。
根本不是Nginx没配好,而是构建时CSS里写的相对路径,和容器内真实文件结构对不上。比如Vite默认打包出dist/css/app.css,里面写url(../fonts/icon.woff),浏览器就会请求/fonts/icon.woff;但你COPY dist/ /usr/share/nginx/html/后,字体实际在/usr/share/nginx/html/fonts/icon.woff,Nginx根目录下根本没有/fonts/这个路径。
验证方法:docker exec -it <container> grep -r "url(" /usr/share/nginx/html/css/</container>,如果满屏../,说明构建阶段就没处理好。
ls -R /usr/share/nginx/html/ | head -20确认fonts/和css/是否同级file://协议双击HTML会失效,因为/fonts/被解析成磁盘根目录,这不是容器问题,是协议限制相对路径靠不住,所有资源URL得从构建阶段就带明确前缀,且必须和Nginx规则对齐。设成./或空字符串,进容器照样404。
vite.config.ts里写base: '/static/',这样url('@/assets/logo.png')打包后变成/static/assets/logo.xxxx.png
vue.config.js里设publicPath: '/static/',确保index.html中link和CSS里url()都带/static/前缀publicPath: './'——它生成的是相对路径,子路径部署(如/my-app/)时会错位alias容易少一层路径,root更直观可靠。假设你把整个dist/拷到/usr/share/nginx/html/,那/static/就该对应这个目录下的static/子目录。
立即学习“前端免费学习笔记(深入)”;
location ^~ /static/ { root /usr/share/nginx/html; } → 请求/static/css/app.css映射到/usr/share/nginx/html/static/css/app.css
location /static/ { alias /usr/share/nginx/html/static/; } → 请求/static/css/app.css会去找/usr/share/nginx/html/css/app.css(static/被截掉了)include /etc/nginx/conf.d/*.conf,把静态规则文件名设为00-static.conf,确保它比location / { }先加载别只刷页面,要逐层确认前端、容器、Nginx三端是否一致。
grep -r "/static/" dist/,确认CSS、JS、HTML里所有资源URL都带/static/
docker exec -it <container> ls -l /usr/share/nginx/html/static/fonts/</container>,确认文件真存在docker logs <nginx-container> | grep "GET /static/.* 404"</nginx-container>,如果有输出,说明请求发到了Nginx但没找到文件,问题还在路径映射最常被忽略的是:前端base和Nginxlocation值不一致,比如一个设/assets/,另一个配/static/,中间差了一层,怎么调都404。