Improvement #172
Updated by Papassorn Phopong (Pipe) 14 days ago
# Bff * [x] 3000 = main (new) พี่ไปร์ท * [ ] 3001 = masterdata * [ ] 3002 = jobpost * [ ] 3003 = candidates * [ ] 3004 = users # Process * [x] 4002 = jobpost พี่ไปร์ท * [x] [ ] 4003 = candidates พี่ไปร์ท * [ ] 4006 = jobapplication พี่ไปร์ท * [ ] 4007 = batch พี่ไปร์ท # System * [x] 5001 = masterdata พี่ไปร์ท * [x] 5002 = jobpost พี่ไปร์ท * [x] 5003 = candidates พี่เจ * [x] 5004 = users พี่ไปร์ท * [x] 5005 = document พี่ไปร์ท * [x] 5006 = jobapplication พี่เจ * [x] 5007 = batch พี่เจ * [ ] 5008 = candidate-consumer พี่เจ * [x] 5011 = job-appointment ก้อง * [ ] 5012 = notification ก้อง * [x] xxxx = jobpost-consumer พี่ไปร์ท ================== ### Dockerfile please backup name (Dockerfile.backup) ### Dockerfile ``` # ---------------------------------------------------- # Stage 1: Build the Application # ---------------------------------------------------- FROM node:24.11.0-alpine3.22 AS builder # Install build dependencies in a single layer RUN apk update && \ apk add --no-cache \ tzdata \ busybox-extras \ openssl \ libssl3 \ libc6-compat && \ cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && \ rm -rf /var/cache/apk/* WORKDIR /app # Copy package files for dependency installation COPY package*.json ./ # Install all dependencies (including devDependencies for build) RUN npm install && \ npm cache clean --force # Copy source code COPY . . # Build application RUN npm run build # ---------------------------------------------------- # Stage 2: Production Image (Minimal & Secure) # ---------------------------------------------------- FROM node:24.11.0-alpine3.22 AS production # Install runtime dependencies RUN apk update && \ apk add --no-cache \ tzdata \ openssl \ libssl3 \ libc6-compat \ dumb-init && \ cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && \ rm -rf /var/cache/apk/* WORKDIR /app # Set NODE_ENV ARG NODE_ENV=prod ENV NODE_ENV=${NODE_ENV} # Copy package files COPY --from=builder /app/package*.json ./ # Install production dependencies only RUN npm install --omit=dev && \ npm cache clean --force # Copy compiled application COPY --from=builder /app/dist/src ./dist COPY --from=builder /app/dist/config ./config COPY --from=builder /app/env ./env # Set ownership RUN chown -R node:node /app # Use non-root user USER node # Set port configuration ARG APPLICATION_PORT=80 ENV PORT=${APPLICATION_PORT} EXPOSE ${APPLICATION_PORT} # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ CMD node -e "require('http').get('http://localhost:' + process.env.PORT + '/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" # Use dumb-init for proper signal handling CMD ["dumb-init", "node", "dist/main"] ``` # package.json ## เพิ่ม ``` "start:pre": "cross-env NODE_ENV=pre nest start", ``` # config/env.ts ## แก้เป็น ``` export enum ENV { DEV = "dev", UAT = "uat", SIT = "sit", PROD = "prod", PRE = "pre", } ``` # env.dev ## ลบ prefix ให้เป็นตามในตัวอย่าง ``` SYSTEM_JOB_POST_BASE_URL=http://localhost:5002/v1 ``` # env.uat ## แก้ port=80 ## แก้ตาม prefix ให้ตรงตามตัวอย่าง ``` SYSTEM_JOB_POST_BASE_URL=http://hrr-system-jobpost-svc.development.svc.cluster.local ``` # env.sit ## copy env.uat มาเป็นตัวตั้งและเปลี่ยน NODE_ENV=sit # env.pre ## copy env.uat มาเป็นตัวตั้งและเปลี่ยน NODE_ENV=pre # env.prod ## copy env.uat มาเป็นตัวตั้งและเปลี่ยน NODE_ENV=prod # main.ts ## enableCors ตามตัวอย่าง ```javascript app.enableCors({ origin: CORS_ORIGIN, credentials: false, methods: ["GET", "POST", "OPTIONS"], allowedHeaders: [ "Content-Type", "Authorization", "X-Request-ID", "sender", "refer", "forward", "senddate", "clientid", ], exposedHeaders: ["X-Request-ID"], }); ``` ## ลบ ``` app.setGlobalPrefix(`${API_PREFIX}/${API_VERSION}`); ``` ## เพิ่ม ```javascript // Enable API versioning app.enableVersioning({ type: VersioningType.URI, defaultVersion: "1", prefix: "v", }); ``` # modules/health/controllers/health.controller.ts ## แก้ตามตัวอย่างทั้งไฟล์ ```javascript import { Controller, Get, VERSION_NEUTRAL } from "@nestjs/common"; import { SkipEnvelope } from "@shared/http/skip-envelope.decorator"; @Controller({ version: VERSION_NEUTRAL }) export class HealthController { @Get("health") @SkipEnvelope() health(): { status: string } { return { status: "ok" }; } @Get("alive") @SkipEnvelope() alive(): { status: string } { return { status: "ok" }; } } ``` # ถ้าไม่มีไฟล์ @shared/http/skip-envelope.decorator.ts ให้เพิ่ม ``` javascript import { SetMetadata } from "@nestjs/common"; export const SKIP_ENVELOPE_KEY = "skipEnvelope"; export const SkipEnvelope = () => SetMetadata(SKIP_ENVELOPE_KEY, true); ```