# ── Stage 1: Build ────────────────────────────────────────────────────────── FROM node:24-alpine AS build WORKDIR /app # build context 为仓库根;先复制 lock 文件,充分利用层缓存 COPY admin-xy/web/package.json admin-xy/web/package-lock.json ./ RUN npm ci --no-audit --no-fund # 复制前端源码并构建 # vite 自身的 transform 流水线不依赖 tsc 解析,类型检查由本地开发阶段保障。 COPY admin-xy/web/ . RUN npx vite build # ── Stage 2: Runtime ───────────────────────────────────────────────────────── FROM nginx:stable-alpine AS runtime # 移除默认配置,写入自定义配置 RUN rm /etc/nginx/conf.d/default.conf COPY --from=build /app/dist /usr/share/nginx/html # nginx 配置:SPA fallback + 反代 /api 到后端 RUN cat > /etc/nginx/conf.d/admin-xy.conf <<'EOF' server { listen 9001; server_name _; root /usr/share/nginx/html; index index.html; # SPA fallback:所有非文件请求都返回 index.html location / { try_files $uri $uri/ /index.html; } # 反代 /api 到后端服务 location /api/ { proxy_pass http://server:9010/api/; proxy_set_header Host $host; 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 ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { expires 30d; add_header Cache-Control "public, no-transform"; } } EOF EXPOSE 9001 CMD ["nginx", "-g", "daemon off;"]