ویژگی تصویر

استفاده از Docker برای پروژه Node.js — راهنمای جامع

  /  Node.js   /  استفاده از Docker برای پروژه Node.js
بنر تبلیغاتی الف
NodeJS - Node.js

Docker به توسعه‌دهندگان Node.js اجازه می‌دهد محیط اجرای برنامه را بسته‌بندی کرده و از اختلافات بین ماشین‌های توسعه، تست و تولید جلوگیری کند. در این مقاله به کاربردهای عملی، نمونه‌های کد، بهترین شیوه‌ها و نکات بهینه‌سازی می‌پردازیم تا بتوانید پروژه Node.js خود را با اطمینان در کانتینرها اجرا کنید.

چرا Docker برای پروژه‌های Node.js مفید است؟

  • قابلیت تکرارپذیری محیط: نسخهٔ Node، وابستگی‌ها و تنظیمات ثابت می‌مانند.
  • تفکیک سرویس‌ها: هر سرویس در کانتینر جدا اجرا می‌شود و از برخورد وابستگی‌ها جلوگیری می‌شود.
  • سازگاری با CI/CD: ساخت ایمیج‌ها و تست خودکار ساده می‌شود.
  • استقرار آسان روی سرویس‌های ابری یا Kubernetes.

ساختار پایه Dockerfile برای تولید (Production)

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/index.js"]

توضیح: این Dockerfile از multi-stage build استفاده می‌کند. در مرحلهٔ اول (builder) فقط وابستگی‌ها نصب و اپلیکیشن ساخته می‌شود. سپس در ایمیج نهایی فقط فایل‌های لازم (باندل ساخته‌شده و node_modules) کپی می‌شوند تا حجم ایمیج کمتر و امن‌تر باشد. دستور USER node به اجرای کانتینر با کاربر غیر روت کمک می‌کند.

نمونه Dockerfile توسعه (Dev) با hot-reload

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm install -g nodemon
EXPOSE 3000
CMD ["nodemon", "--legacy-watch", "src/index.js"]

توضیح: این نسخه مناسب محیط توسعه است. nodemon برای بارگذاری خودکار تغییرات استفاده می‌شود. در توسعه معمولاً از volume برای اتصال سورس‌کد محلی به کانتینر استفاده می‌کنیم تا تغییرات بلافاصله دیده شوند.

docker-compose برای توسعه و تست

version: "3.8"
services:
  app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development

توضیح: docker-compose کانتینر برنامه را همراه با volume برای کدنویسی زنده راه‌اندازی می‌کند. volume /app/node_modules باعث می‌شود ماژول‌های نصب‌شده در کانتینر از روی سیستم میزبان بازنویسی نشوند. پورت 3000 به میزبان متصل شده تا بتوانید اپ را در مرورگر ببینید.

فایل .dockerignore

node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
.gitignore

توضیح: .dockerignore جلوی کپی فایل‌های غیرضروری به context داکر را می‌گیرد و باعث افزایش سرعت build و کاهش حجم می‌شود. همیشه node_modules را نادیده بگیرید مگر در شرایط خاص که نیاز دارید.

بهینه‌سازی لایه‌ها و کش

  • ترتیب دستورات مهم است: ابتدا فایل‌های package.json را کپی کنید و وابستگی‌ها را نصب کنید تا از کش لایه‌ها بیشتر استفاده شود.
  • از npm ci در CI استفاده کنید تا نصب وابستگی‌ها سریع‌تر و تکرارپذیرتر باشد.
  • multi-stage builds برای حذف ابزارهای توسعه و کاهش حجم نهایی ضروری است.

بهترین شیوه‌های امنیتی

  • کانتینر را با کاربر غیر روت اجرا کنید (USER node).
  • متغیرهای حساس را در فایل‌های محیط یا secrets مدیر مانند Docker secrets یا Vault ذخیره کنید، نه در کد یا Dockerfile.
  • در صورت امکان از نسخه‌های Alpine یا slim استفاده کنید اما مراقب وابستگی‌های native باشید.

نکات دیباگ و لاگ

برای دیباگ محلی از mount کردن سورس و اجرای nodemon استفاده کنید. برای مشاهده لاگ‌ها در محیط تولید بهتر است از stdout/stderr استفاده کنید و لاگ‌ها را به سیستم logging مرکزی (مثل ELK یا Loki) ارسال کنید. استفاده از HEALTHCHECK در Dockerfile سلامت سرویس را گزارش می‌دهد.

نمونه HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s 
  CMD wget -qO- http://localhost:3000/health || exit 1

توضیح: این دستور وضعیت اپ را هر 30 ثانیه چک می‌کند. اگر endpoint /health پاسخ مناسب ندهد، Docker کانتینر را ناسالم گزارش می‌کند که در orchestrator‌ها قابل استفاده است.

مقایسه سریع: توسعه vs تولید

موضوعتوسعهتولید
وابستگی‌هاnpm install، شامل devDependenciesnpm ci –only=production
Volumeسورس محلی mount می‌شودفایل‌ها در ایمیج بسته‌بندی می‌شوند
امنیتممکن است کمتر حساسکاربر غیر روت، secrets مدیریت‌شده

مشکلات رایج و راه‌حل‌شان

  • حجم زیاد ایمیج: از multi-stage و حذف فایل‌های غیرضروری استفاده کنید.
  • مشکل با native modules (مثل bcrypt): از تصاویر با libc مناسب یا ساخت در مرحلهٔ builder استفاده کنید.
  • تغییرات کد در dev دیده نمی‌شود: volume را درست تنظیم کنید و nodemon با –legacy-watch برای بعضی سیستم‌فایل‌ها مفید است.

خلاصه و پیشنهادات عملی

برای شروع سریع: یک Dockerfile multi-stage بسازید، .dockerignore را تنظیم کنید، و docker-compose برای توسعه بسازید. در CI از npm ci و تصاویر بر پایهٔ slim/alpine استفاده کنید. همیشه متغیرهای حساس را خارج از Dockerfile نگه دارید و کانتینرها را با دسترسی حداقلی اجرا کنید.

با رعایت این نکات می‌توانید محیط توسعه قابل اعتماد و فرایند استقرار امن و قابل تکرار برای پروژه‌های Node.js خود ایجاد کنید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: