تكرار السؤال: …
الإجابة المختصرة
استخدام Multi-Stage Builds لتقليل الحجم، والتشغيل بحساب مستخدم غير جذري (non-root)، واستخدام dumb-init كـ PID 1 لمعالجة إشارات النظام بلباقة.
الشرح
الهدف هو بناء صور صغيرة وآمنة. الممارسات تشمل: 1) استخدام Multi-Stage Build لترجمة TypeScript وتثبيت devDependencies ثم نسخ ملفات الإنتاج فقط إلى الصورة النهائية، 2) عدم تشغيل التطبيق كـ root بل بحساب node المدمج، 3) استخدام أداة تهيئة مثل dumb-init أو tini لتشغيل العملية كـ PID 1 لضمان وصول إشارات SIGTERM وSIGINT لعملية Node.js بدقة وإغلاق العمليات اليتيمة (Zombie processes).
مثال بالكود
FROM node:24-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --omit=dev # keep only production dependencies
FROM node:24-alpine
RUN apk add --no-cache dumb-init # a proper PID 1 that forwards SIGTERM/SIGINT
ENV NODE_ENV=production
WORKDIR /app
COPY --from=build --chown=node:node /app/node_modules ./node_modules
COPY --from=build --chown=node:node /app/dist ./dist
COPY --from=build --chown=node:node /app/package*.json ./
USER node # never run as root
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/index.js"]أخطاء شائعة
- نسخ مجلد node_modules بالكامل من جهاز التطوير إلى داخل صورة Docker.