|
1 | | -FROM node:22-alpine |
| 1 | +# Multi-stage build for optimal image size |
| 2 | +FROM node:lts-alpine AS base |
2 | 3 |
|
| 4 | +# Install dependencies only when needed |
| 5 | +FROM base AS deps |
| 6 | +RUN apk add --no-cache libc6-compat wget openssl |
3 | 7 | WORKDIR /app |
4 | 8 |
|
5 | | -COPY package*.json ./ |
| 9 | +# Build-time token for GitHub Packages — never stored in the final image |
| 10 | +ARG NODE_AUTH_TOKEN |
| 11 | +ENV NODE_AUTH_TOKEN=${NODE_AUTH_TOKEN} |
6 | 12 |
|
7 | | -RUN npm ci |
| 13 | +# Copy package files |
| 14 | +COPY .npmrc package.json yarn.lock* ./ |
8 | 15 |
|
| 16 | +# Install dependencies, then remove .npmrc so the token is not cached |
| 17 | +RUN yarn --frozen-lockfile --production=false && rm -f .npmrc |
| 18 | + |
| 19 | +# Build the source code |
| 20 | +FROM base AS builder |
| 21 | +RUN apk add --no-cache wget openssl |
| 22 | +WORKDIR /app |
| 23 | +COPY --from=deps /app/node_modules ./node_modules |
9 | 24 | COPY . . |
10 | 25 |
|
11 | | -RUN npm run build |
| 26 | +# Build application |
| 27 | +RUN yarn build |
| 28 | + |
| 29 | +# Production image, copy all the files and run the app |
| 30 | +FROM base AS runner |
| 31 | +RUN apk add --no-cache wget openssl |
| 32 | +WORKDIR /app |
| 33 | + |
| 34 | +# Create non-root user for security |
| 35 | +RUN addgroup --system --gid 1001 nodejs |
| 36 | +RUN adduser --system --uid 1001 nestjs |
| 37 | + |
| 38 | +# Copy necessary files from builder stage |
| 39 | +COPY --from=builder /app/dist ./dist |
| 40 | +COPY --from=builder /app/package.json ./package.json |
| 41 | +COPY --from=builder /app/yarn.lock ./yarn.lock |
| 42 | + |
| 43 | +# Copy node_modules from deps stage (production only) |
| 44 | +COPY --from=deps /app/node_modules ./node_modules |
| 45 | + |
| 46 | +# Change ownership to nestjs user |
| 47 | +RUN chown -R nestjs:nodejs /app |
| 48 | +USER nestjs |
| 49 | + |
| 50 | +CMD ["yarn", "start"] |
12 | 51 |
|
13 | | -CMD ["node", "dist/main"] |
|
0 commit comments