# syntax=docker/dockerfile:1.6 ########## Base (apk + common tools ติดตั้งตอน build) ########## FROM node:20-alpine AS base WORKDIR /app RUN apk add --no-cache bash curl tzdata python3 make g++ \ && ln -snf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime \ && echo "Asia/Bangkok" > /etc/timezone ENV TZ=Asia/Bangkok APP_HOME=/app RUNTIME_HOME=/opt/runtime ########## Deps สำหรับ Production (no devDeps) ########## FROM base AS deps-prod WORKDIR /work COPY package*.json ./ RUN npm ci --omit=dev || npm install --omit=dev RUN mkdir -p ${RUNTIME_HOME} && mv node_modules ${RUNTIME_HOME}/node_modules ########## Deps สำหรับ Development (รวม devDeps) ########## FROM base AS deps-dev RUN apk add --no-cache git openssh-client ca-certificates WORKDIR /work COPY package*.json ./ RUN npm ci || npm install RUN mkdir -p ${RUNTIME_HOME} && mv node_modules ${RUNTIME_HOME}/node_modules ########## Runtime: Development ########## FROM base AS dev WORKDIR /app # ทำงานเป็น root ชั่วคราวเพื่อจัดสิทธิ์/ลิงก์ แล้วค่อยเปลี่ยนเป็น node # 1) คัดลอก deps dev COPY --from=deps-dev /opt/runtime/node_modules /opt/runtime/node_modules # 2) สร้าง symlink /app/node_modules → /opt/runtime/node_modules (กันปัญหา NODE_PATH/permission) RUN ln -sfn /opt/runtime/node_modules /app/node_modules \ && chown -R node:node /app # 3) ใส่สคริปต์ start-dev แล้วค่อยสลับ USER COPY --chown=node:node ./start-dev.sh /app/start-dev.sh RUN chmod +x /app/start-dev.sh USER node # ให้หา nodemon ได้จาก node_modules/.bin ที่ bake มาแล้ว # ENV NODE_ENV=development PATH="/opt/runtime/node_modules/.bin:${PATH}" # ให้หา nodemon ได้ และระบุพอร์ตดีฟอลต์ ENV NODE_ENV=development \ PORT=3001 \ PATH="/opt/runtime/node_modules/.bin:${PATH}" EXPOSE 3001 9229 HEALTHCHECK --interval=15s --timeout=5s --retries=10 \ CMD wget -qO- http://127.0.0.1:3001/health || exit 1 # HEALTHCHECK --interval=15s --timeout=5s --retries=10 CMD curl -fsS http://127.0.0.1:7001/health || exit 1 CMD ["/app/start-dev.sh"] ########## Runtime: Production ########## FROM base AS prod WORKDIR /app ENV NODE_ENV=production # ใส่ deps สำหรับ prod COPY --from=deps-prod /opt/runtime/node_modules /opt/runtime/node_modules # สร้าง symlink เช่นกัน เพื่อให้ Node resolve deps ได้จาก /app เหมือน dev RUN ln -sfn /opt/runtime/node_modules /app/node_modules # ใส่ซอร์ส (prod ไม่ bind โค้ด) COPY . . USER node EXPOSE 3001 HEALTHCHECK --interval=30s --timeout=5s --retries=10 \ CMD wget -qO- http://127.0.0.1:3001/health || exit 1 CMD ["node","src/index.js"]