# Task Scheduler Dockerfile(Phase 1) # # 設計重點(T10 補強): # 1. 用 node:18-alpine —— 最小化 image 大小(~150MB vs node:18 的 ~1GB) # 2. 兩階段:先複製 package*.json + npm ci,再 COPY 其他檔,善用 Docker 層快取 # 3. 只裝 production deps(--only=production / --omit=dev)—— jest / nodemon 不進 image # 4. 非 root user 執行,降低 RCE 後的影響面 # 5. .dockerignore 已排除 .env / tests / node_modules / IDE 設定 # 6. HEALTHCHECK 對接 /health 端點(T8 已實作) # 7. 環境變數透過 docker-compose / Kubernetes secret 注入,不在 image 內 FROM node:18-alpine WORKDIR /app # curl 只給 HEALTHCHECK 用;alpine 預設無 RUN apk add --no-cache curl # === 第一層:依賴(變動較少,快取友善)=== # 先 COPY package*.json,npm ci 後再 COPY 原始碼,避免改 src 就 invalidate npm install 層 COPY package*.json ./ # --omit=dev 對齊新版 npm(替代 --only=production);jest / nodemon 等 devDependencies 不會被裝 RUN npm ci --omit=dev && npm cache clean --force # === 第二層:原始碼 === # .dockerignore 已排除 .env / tests / __tests__ / node_modules,這裡 COPY . . 是安全的 COPY . . # === 安全:非 root user === RUN addgroup -g 1001 -S appgroup && \ adduser -S appuser -u 1001 -G appgroup # 建立 job data dir 並改 owner(worker / scheduler 共用 volume 用) RUN mkdir -p /data/jobs && chown -R appuser:appgroup /app /data/jobs USER appuser EXPOSE 4000 # Health check 對接 /health 端點(T8:含 redis / Member Center / FAA reachability) HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ CMD curl -f http://localhost:4000/health || exit 1 # 啟動:直接 node server.js(不用 npm start)以利 SIGTERM signal 直接送到 node # - npm start 會 fork 一層,SIGTERM 不一定傳到 child,影響 graceful shutdown CMD ["node", "server.js"]