Files
xiaoxia-saas/infra/docker/web.Dockerfile
T
xiaoxia fa65a401a5
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / PR Build API Image (pull_request) Failing after 23s
CI/CD Pipeline / PR Build Worker Image (pull_request) Failing after 23s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 56s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 1m26s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 1m27s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m44s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 5m13s
AI Code Review / AI Code Review (pull_request) Successful in 6m17s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 6m41s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 2s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m9s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 126h33m42s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 126h33m43s
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Failing after 126h40m16s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 126h40m21s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 126h40m10s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 126h40m11s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 126h39m53s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 126h39m59s
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Failing after 126h40m3s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Failing after 126h40m4s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 126h40m8s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 126h40m8s
CI/CD Pipeline / Check push changed paths (pull_request) Failing after 126h40m15s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 126h39m53s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 126h33m30s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 126h33m30s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 126h33m29s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 126h39m53s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 126h40m10s
fix(web): bake all nginx configs into image, select via APP_ENV at runtime
Problem: web Dockerfile used ARG NGINX_CONF to bake a single nginx config
at build time. CI always built from develop branch with nginx-staging.conf,
so the production image also contained the staging nginx config pointing to
xiaoxia-api-staging:8000, causing 502 in production after restarts.

Fix:
- Bake all 3 nginx configs (default/nginx.conf, nginx-staging.conf,
  nginx-production.conf) into the web image
- Add nginx-entrypoint.sh that symlinks the correct config based on
  APP_ENV (staging/production) at container startup
- Remove NGINX_CONF build arg from CI pipeline (3 occurrences)
- Update deploy scripts to pass APP_ENV to web container
- Update compose.yml to use APP_ENV instead of NGINX_ENV

This ensures a single image artifact works for both staging and production,
with the correct nginx upstream selected at runtime via environment variable.
2026-09-11 08:43:07 +08:00

41 lines
1.7 KiB
Docker
Executable File

# Build stage
FROM git.xiaoxiajianji.com/xiaoxia/base/node:20 AS builder
ARG SOURCE_HASH=""
WORKDIR /app
ARG VITE_API_URL=https://saas-api.xiaoxiajianji.com
ENV VITE_API_URL=$VITE_API_URL
# 先拷依赖清单(缓存友好:依赖不变时直接命中缓存层)
COPY apps/web/package.json apps/web/package-lock.json ./apps/web/
WORKDIR /app/apps/web
# 安装依赖:node_modules写入镜像layer,走ACR缓存保证完整性
# /root/.npm 保留cache mount加速下载(不影响构建正确性)
RUN --mount=type=cache,target=/root/.npm,sharing=locked \
npm ci --registry=https://registry.npmmirror.com
# 再拷源码
COPY apps/web/ ./
# 构建:TS增量编译 + Vite构建,tsbuildinfo用cache mount持久化
# node_modules直接使用镜像中已安装的(layer缓存保证完整性)
# SOURCE_HASH 变化时强制重新执行(防止 buildkit 幽灵缓存命中)
RUN --mount=type=cache,target=/app/apps/web/.tscache,sharing=locked \
mkdir -p .tscache \
&& echo "SOURCE_HASH=${SOURCE_HASH}" > .cache_bust \
&& ./node_modules/.bin/tsc --incremental --tsBuildInfoFile .tscache/tsconfig.tsbuildinfo \
&& ./node_modules/.bin/vite build
# Production stage with nginx
FROM git.xiaoxiajianji.com/xiaoxia/base/nginx:alpine AS runner
WORKDIR /usr/share/nginx/html
COPY --from=builder /app/apps/web/dist ./
# 将所有 nginx 配置烤入镜像,entrypoint 按 APP_ENV 选择
COPY infra/docker/nginx.conf /etc/nginx/nginx-production.conf
COPY infra/docker/nginx-staging.conf /etc/nginx/nginx-staging.conf
COPY infra/docker/nginx-production.conf /etc/nginx/nginx-production.conf
COPY infra/docker/nginx-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/docker-entrypoint.sh"]