2026-08-05 12:11:29 +08:00
|
|
|
# Frontend image: build the SPA with Node, serve the static dist with nginx.
|
|
|
|
|
#
|
|
|
|
|
# Multi-stage so the final image contains ONLY the compiled static assets +
|
|
|
|
|
# nginx — no Node toolchain shipped to production.
|
|
|
|
|
FROM node:20-alpine AS build
|
|
|
|
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
|
|
|
|
# Install deps first (cache-friendly: only re-installs when package*.json
|
|
|
|
|
# changes; node_modules is never copied from the host via .dockerignore).
|
|
|
|
|
COPY package.json package-lock.json* ./
|
2026-09-01 16:30:46 +08:00
|
|
|
# registry 指定 npmmirror(国内构建加速,ECS 上直连 npmjs 慢/超时)
|
|
|
|
|
RUN npm install --no-audit --no-fund --registry=https://registry.npmmirror.com # ci 对锁同步严格,本地/容器 npm 版本差异致 EUSAGE
|
2026-08-05 12:11:29 +08:00
|
|
|
|
|
|
|
|
# Copy sources and build the production bundle into ./dist.
|
|
|
|
|
COPY tsconfig*.json vite.config.ts index.html ./
|
|
|
|
|
COPY public/ ./public/
|
|
|
|
|
COPY src/ ./src/
|
|
|
|
|
RUN npm run build
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
# Runtime stage: nginx serves the static dist and reverse-proxies /api.
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
FROM nginx:1.27-alpine
|
|
|
|
|
|
|
|
|
|
# Replace the default nginx config with our /api proxy + SPA fallback.
|
|
|
|
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
|
|
|
|
|
|
|
|
# Copy the build output from the build stage into nginx's html root.
|
|
|
|
|
COPY --from=build /app/dist /usr/share/nginx/html
|
|
|
|
|
|
|
|
|
|
EXPOSE 80
|
|
|
|
|
|
|
|
|
|
# nginx foregrounds by default with the ``nginx -g 'daemon off;'`` directive
|
|
|
|
|
# already set on the official image; no CMD override needed.
|