Angular 9部署于Nginx下assets资源加载404问题求助
嘿,我来帮你搞定这个assets加载失败的问题!咱们先理清楚核心矛盾:你的Angular应用编译时指定了--deploy-url=/app/,所以打包后的资源都指向了/app/assets/,但Nginx把应用部署在了/route1/route2路径下,当用户访问这个路径时,应用会默认从当前路由路径(也就是/route1/route2/)下去找assets,这就导致了路径不匹配,资源自然加载失败。
下面分三步来解决:
1. 修正Angular编译参数
你需要把base-href和deploy-url都改成和Nginx部署路径一致的值,也就是/route1/route2/。修改后的编译命令应该是:
npm run ng build -- --base-href=/route1/route2/ --deploy-url=/route1/route2/
--base-href:告诉Angular应用的基础路由和资源加载的根路径,确保路由跳转和资源请求都基于这个路径--deploy-url:专门指定静态资源(assets、js、css这些)的加载前缀,保证资源请求地址完全匹配Nginx的部署路径
2. 调整Nginx配置
当前的Nginx配置里,try_files指向了/app/index.html,但你的编译产物是直接放在/usr/share/nginx/html下的,这明显不对。咱们把配置改成这样:
worker_processes 4; events { worker_connections 4096; } http { server { listen 8080; root /usr/share/nginx/html; include /etc/nginx/mime.types; location /route1/route2 { # 先找实际存在的文件/目录,找不到就fallback到Angular的index.html(保证SPA路由正常) try_files $uri $uri/ /route1/route2/index.html; } } }
这里的关键是try_files的最后一个参数要和部署路径对齐,这样Nginx才能正确找到Angular的入口文件,同时静态资源请求也能匹配到实际的文件位置。
3. 对齐Dockerfile的文件复制路径
从你的Dockerfile来看,编译后的产物是/app-ui/dist,假设里面的app文件夹就是Angular打包后的所有文件(index.html、assets、js/css等),那咱们需要把这个文件夹复制到Nginx的/usr/share/nginx/html/route1/route2目录下,这样Nginx访问/route1/route2时就能直接对应到这个目录的文件。修改后的Dockerfile:
ARG mode ### STAGE 1: Build ### FROM node:alpine AS build COPY package.json package-lock.json ./ RUN npm install && mkdir /app-ui && mv ./node_modules ./app-ui WORKDIR /app-ui COPY . . # 用修正后的编译参数 RUN npm run ng build -- --base-href=/route1/route2/ --deploy-url=/route1/route2/ ### STAGE 2: Run ### FROM nginx:alpine COPY ./nginx/nginx.conf /etc/nginx/nginx.conf RUN rm -rf /usr/share/nginx/html/* # 将编译后的app文件夹复制到Nginx的目标子路径下 COPY --from=build /app-ui/dist/app /usr/share/nginx/html/route1/route2
最后验证一下
- 重新构建镜像:
docker build --build-arg mode=production -t angular-app . - 启动容器:
docker run -p 8080:8080 angular-app - 访问
localhost:8080/route1/route2,打开浏览器控制台看网络请求,你会发现assets的请求路径变成了/route1/route2/assets/...,而且能正常返回200状态码,问题就解决啦!
简单总结下:之前的问题就是deploy-url和部署路径不匹配,加上Nginx配置和Docker文件复制路径没对齐,导致资源找不到。调整这三个点就完美解决了。
内容的提问来源于stack exchange,提问作者Erik

