# EN: Multi-stage Docker build for production-ready microservice # VI: Multi-stage Docker build cho microservice production-ready # EN: Base stage with security updates # VI: Base stage với security updates # EN: Base stage with security updates (Node 25) # VI: Base stage với security updates (Node 25) FROM node:25-alpine AS base # EN: Install security updates and required packages # VI: Cài đặt security updates và packages cần thiết RUN apk update && apk upgrade && \ apk add --no-cache \ libc6-compat \ dumb-init \ su-exec \ && rm -rf /var/cache/apk/* # EN: Create app directory with correct permissions # VI: Tạo app directory với permissions đúng WORKDIR /app RUN chown node:node /app USER node # EN: Dependencies stage - separate for better caching # VI: Dependencies stage - tách riêng để cache tốt hơn FROM base AS deps USER root RUN chown node:node /app USER node # EN: Enable corepack for pnpm # VI: Enable corepack cho pnpm USER root RUN corepack enable pnpm USER node # EN: Copy source code (files must be owned by node user for pnpm to write) # VI: Copy source code (files phải thuộc về node user để pnpm có thể ghi) COPY --chown=node:node . . # EN: Install dependencies for iam-service only with hoisting # VI: Chỉ cài đặt dependencies cho iam-service với hoisting # EN: --shamefully-hoist creates flat node_modules without symlinks # VI: --shamefully-hoist tạo node_modules phẳng không có symlinks RUN pnpm install --frozen-lockfile=false --shamefully-hoist --filter @goodgo/iam-service... # EN: Generate Prisma Client explicitly # VI: Generate Prisma Client một cách rõ ràng RUN cd services/iam-service && npx prisma generate # EN: Build all packages that iam-service depends on # VI: Build tất cả packages mà iam-service phụ thuộc RUN pnpm --filter @goodgo/iam-service... build # EN: Remove dev dependencies to reduce size # VI: Xóa dev dependencies để giảm size RUN rm -rf services/iam-service/node_modules/.pnpm/*-dev-* && \ rm -rf node_modules/.pnpm/*@types+* && \ rm -rf node_modules/.pnpm/*eslint* && \ rm -rf node_modules/.pnpm/*jest* && \ rm -rf node_modules/.pnpm/*typescript* && \ rm -rf node_modules/.pnpm/*ts-* && \ rm -rf node_modules/.pnpm/*prettier* # EN: Production stage - minimal runtime image # VI: Production stage - minimal runtime image FROM base AS runner # EN: Install runtime dependencies (curl for healthcheck, dumb-init for signal handling, openssl for Prisma) # VI: Cài đặt runtime dependencies (curl cho healthcheck, dumb-init cho signal handling, openssl cho Prisma) USER root RUN apk add --no-cache \ curl \ openssl \ && rm -rf /var/cache/apk/* # EN: Create non-root user for security # VI: Tạo non-root user cho security RUN addgroup -g 1001 -S nodejs && \ adduser -S microservice -u 1001 # EN: Create necessary directories with correct permissions # VI: Tạo necessary directories với permissions đúng RUN mkdir -p /app && \ chown -R microservice:nodejs /app # EN: Switch to non-root user # VI: Switch sang non-root user USER microservice # EN: Copy entire /app but .dockerignore will exclude source files # VI: Copy toàn bộ /app nhưng .dockerignore sẽ loại trừ source files # EN: This preserves pnpm workspace symlinks while excluding unnecessary files # VI: Điều này giữ nguyên pnpm workspace symlinks trong khi loại trừ files không cần COPY --from=deps --chown=microservice:nodejs /app /app WORKDIR /app/services/iam-service # EN: Add health check # VI: Thêm health check HEALTHCHECK --interval=30s --timeout=3s \ CMD wget -qO- http://localhost:5001/health/live || exit 1 # EN: Use dumb-init to handle signals properly # VI: Sử dụng dumb-init để handle signals properly ENTRYPOINT ["dumb-init", "--"] # EN: Start the service from the correct location # VI: Khởi động service từ đúng vị trí CMD ["node", "dist/main.js"]