# Base image (WACE Docker Hub) FROM dockerhub.wace.me/node:20.19-alpine.linux AS base WORKDIR /app ENV NODE_ENV=production # Install OpenSSL, curl (for healthcheck), and required certs RUN apk add --no-cache openssl ca-certificates curl # Dependencies stage (install production dependencies) FROM base AS deps COPY package*.json ./ RUN npm ci --omit=dev --prefer-offline --no-audit && npm cache clean --force # Build stage (compile TypeScript) FROM dockerhub.wace.me/node:20.19-alpine.linux AS build WORKDIR /app COPY package*.json ./ RUN npm ci --prefer-offline --no-audit && npm cache clean --force COPY tsconfig.json ./ COPY src ./src RUN npm run build # Runtime image - base 이미지 재사용으로 중복 설치 제거 FROM base AS runner ENV NODE_ENV=production # Create non-root user (Alpine 방식) RUN addgroup -S appgroup && adduser -S -G appgroup appuser # Copy production node_modules COPY --from=deps /app/node_modules ./node_modules # Copy built files COPY --from=build /app/dist ./dist # Copy package files COPY package*.json ./ # 루트 디렉토리만 생성하고 appuser에게 쓰기 권한 부여 # 하위 디렉토리는 애플리케이션이 런타임에 자동 생성 RUN mkdir -p logs uploads data && \ chown -R appuser:appgroup /app && \ chmod -R 755 /app EXPOSE 3001 USER appuser CMD ["node", "dist/app.js"]