1- # Base Node.js image
1+ # ======================
2+ # Base
3+ # ======================
24FROM node:20-alpine AS base
5+ WORKDIR /app
6+ RUN apk add --no-cache libc6-compat
37
48# ======================
5- # Set build arguments for COS credentials
9+ # Dependencies
610# ======================
7- ENV COS_SECRET_ID=$COS_SECRET_ID
8- ENV COS_SECRET_KEY=$COS_SECRET_KEY
9- ENV COS_BUCKET=$COS_BUCKET
10- ENV COS_REGION=$COS_REGION
11-
12- # Install dependencies only when needed
1311FROM base AS deps
1412
15- WORKDIR /app
16-
17- RUN apk add --no-cache ca-certificates curl
18-
1913RUN corepack enable && corepack prepare pnpm@latest --activate
2014
21- RUN pnpm config set registry https://registry.npmmirror.com \
22- && pnpm config set fetch-timeout 600000 \
23- && pnpm config set fetch-retries 5
24-
25- # Copy package files
26- COPY package.json pnpm-lock.yaml* ./
15+ COPY package.json pnpm-lock.yaml ./
2716
2817RUN pnpm install --frozen-lockfile
2918
30- # Rebuild the source code only when needed
19+ # ======================
20+ # Builder
21+ # ======================
3122FROM base AS builder
3223WORKDIR /app
3324
34- # Copy node_modules from deps
3525COPY --from=deps /app/node_modules ./node_modules
36-
37- # Copy all project files
3826COPY . .
3927
40- # Set Next.js telemetry to disabled
4128ENV NEXT_TELEMETRY_DISABLED=1
4229
43- # Copy production environment variables for build
44- COPY .env.production .env.production
45-
46- # Build the application
4730RUN npm run build
4831
49- # Verify standalone build was created
50- RUN ls -la .next/ && \
51- if [ ! -d ".next/standalone" ]; then \
52- echo "ERROR: .next/standalone directory not found. Make sure output: 'standalone' is set in next.config.ts" ; \
53- exit 1; \
54- fi
55-
56- RUN wget https://cosbrowser.cloud.tencent.com/software/coscli/coscli-linux-amd64 -O /usr/local/bin/coscli && \
57- chmod +x /usr/local/bin/coscli && \
58- coscli --version
32+ # 确保 standalone 存在
33+ RUN test -d .next/standalone
5934
6035# ======================
61- # Upload static files to COS
36+ # Runtime
6237# ======================
63- RUN coscli sync .next/static cos://${COS_BUCKET}/next-static/ \
64- --region $COS_REGION --force && \
65- coscli sync public cos://${COS_BUCKET}/public/ \
66- --region $COS_REGION --force
67-
68- # Production image, copy all the files and run next
69- FROM base AS runner
38+ FROM node:20-alpine AS runner
7039WORKDIR /app
7140
72- # Set environment variables
7341ENV NODE_ENV=production
7442ENV NEXT_TELEMETRY_DISABLED=1
7543
76- # Create a non-root user
7744RUN addgroup --system --gid 1001 nodejs && \
7845 adduser --system --uid 1001 nextjs
7946
80- # Copy public assets
81- COPY --from=builder /app/public ./public
82-
83- # Copy standalone application
8447COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
85-
86- # Copy static assets
8748COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
49+ COPY --from=builder --chown=nextjs:nodejs /app/public ./public
8850
89- # Switch to non-root user
9051USER nextjs
9152
92- # Expose application port
9353EXPOSE 3000
94-
95- # Set environment variable for port
9654ENV PORT=3000
9755ENV HOSTNAME=0.0.0.0
9856
99- # Health check to verify container is running properly
100- HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
101- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
102-
103- # Start the application
104- CMD ["node" , "server.js" ]
57+ CMD ["node" , "server.js" ]
0 commit comments