Dockerfile 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. # 本文件不指定平台。目标架构由构建命令决定:
  2. # docker build --platform linux/arm64 ...
  3. # 交付构建请走 API 仓库的 scripts/build-release.sh,它统一了两个镜像的平台。
  4. # ---------- build ----------
  5. FROM node:20-alpine AS build
  6. WORKDIR /app
  7. # 镜像里没有 .git,husky install 会失败;HUSKY=0 让它跳过。
  8. ENV HUSKY=0
  9. COPY package.json package-lock.json ./
  10. RUN npm ci
  11. COPY . .
  12. # 这里刻意没有任何 ARG:所有环境相关的配置都走运行时注入(见文件末尾的 ENV)。
  13. # 镜像因此与具体环境无关,同一份产物可以在任何环境跑,换配置只需重启容器。
  14. # 用 build-only 而非 build:跳过 vue-tsc 类型检查,
  15. # 避免既有类型问题阻塞交付镜像的构建。类型检查请在 CI / 本地跑。
  16. RUN npm run build-only
  17. # ---------- runtime ----------
  18. FROM nginx:alpine
  19. COPY --from=build /app/dist /usr/share/nginx/html
  20. COPY nginx.conf /etc/nginx/conf.d/default.conf
  21. # nginx 官方镜像自带的 docker-entrypoint 会在启动时对
  22. # /etc/nginx/templates/*.template 做 envsubst,输出到 NGINX_ENVSUBST_OUTPUT_DIR。
  23. # 这里把输出目录指向静态根,于是生成 /usr/share/nginx/html/config.js,
  24. # 覆盖构建产物里那份空的占位 config.js。不需要自定义 entrypoint。
  25. COPY config.js.template /etc/nginx/templates/config.js.template
  26. ENV NGINX_ENVSUBST_OUTPUT_DIR=/usr/share/nginx/html
  27. # 运行时可配置项。必须给默认值:envsubst 只替换"已定义"的变量,
  28. # 未定义时模板里的 ${XXX} 会被原样保留,变成一个非空的垃圾字符串,
  29. # 反而绕过了代码里的兜底逻辑。
  30. #
  31. # AZURE_SPEECH_* 供前端 TTS(speechService.ts)使用。放在这里而非构建期 ARG,
  32. # 是为了让镜像与环境解耦 —— 但要清楚:它最终会写进浏览器可读的 /config.js,
  33. # 并不比构建期烧入更安全,只是更灵活。详见 DEPLOY.md「已知问题」。
  34. ENV SPEAKING_API_HOST="" \
  35. AZURE_SPEECH_KEY="" \
  36. AZURE_SPEECH_REGION=""
  37. EXPOSE 80