داکرایز کردن اپلیکیشن Node.js؛ از Dockerfile تا Docker Compose

آموزش قدم‌به‌قدم داکرایز کردن پروژه‌ی Node.js با Dockerfile چندمرحله‌ای، کاهش حجم ایمیج، راه‌اندازی MySQL با Docker Compose و نکات امنیتی کانتینرها.

داکرایز کردن اپلیکیشن Node.js؛ از Dockerfile تا Docker Compose
زمان انتشار:
۱۱ مرداد ۱۴۰۵
زمان مطالعه:
حدود 3 دقیقه
نویسنده:
علیرضا مهدی زاده
دسته‌بندی:بک‌انددواپس

چرا باید اپلیکیشن Node.js را داکرایز کنیم؟

احتمالاً شما هم جمله‌ی معروف «روی سیستم من که کار می‌کرد!» را بارها شنیده‌اید. تفاوت نسخه‌ی Node.js، کتابخانه‌های سیستم‌عامل و متغیرهای محیطی بین لپ‌تاپ توسعه‌دهنده و سرور، یکی از رایج‌ترین دلایل خطا در زمان استقرار است. Docker این مشکل را با بسته‌بندی کل محیط اجرای برنامه در یک «ایمیج» حل می‌کند؛ ایمیجی که هر جا اجرا شود، دقیقاً همان رفتار را دارد.

در این مقاله قدم‌به‌قدم یک اپلیکیشن Node.js را داکرایز می‌کنیم، حجم ایمیج را کوچک می‌کنیم و با Docker Compose پایگاه داده را هم کنارش راه می‌اندازیم.

نمای شبانه‌ی یک ساختمان اداری با پنجره‌های روشن؛ استعاره‌ای از کانتینرهای مستقل کنار هم

ایمیج و کانتینر؛ تفاوت در یک نگاه

  • ایمیج (Image): یک قالب فقط‌خواندنی شامل سیستم‌عامل پایه، Node.js، کد و وابستگی‌ها.
  • کانتینر (Container): نمونه‌ی در حال اجرای یک ایمیج. می‌توانید از یک ایمیج ده کانتینر هم‌زمان بسازید.
  • رجیستری (Registry): مخزنی مثل Docker Hub یا یک رجیستری خصوصی برای نگهداری و اشتراک ایمیج‌ها.

نوشتن یک Dockerfile چندمرحله‌ای

بزرگ‌ترین اشتباه مبتدی‌ها، ساخت ایمیجی است که ابزارهای بیلد، کش npm و فایل‌های اضافی را هم با خود حمل می‌کند. با Multi-stage Build مرحله‌ی ساخت را از مرحله‌ی اجرا جدا می‌کنیم:

# ---- مرحله‌ی ساخت ----
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ---- مرحله‌ی اجرا ----
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

به ترتیب دستورها دقت کنید: ابتدا فقط package.json کپی می‌شود تا لایه‌ی نصب وابستگی‌ها کش شود. تا وقتی وابستگی‌ها تغییر نکرده‌اند، بیلدهای بعدی چند ثانیه بیشتر طول نمی‌کشند.

دست توسعه‌دهنده روی موس کنار کیبورد و فنجان قهوه در حال نوشتن Dockerfile

فایل .dockerignore را فراموش نکنید

بدون این فایل، پوشه‌ی node_modules، فایل‌های .env و تاریخچه‌ی Git هم وارد کانتکست بیلد می‌شوند؛ هم بیلد کند می‌شود و هم ممکن است اطلاعات محرمانه داخل ایمیج بماند.

node_modules
.git
.env*
dist
npm-debug.log

راه‌اندازی کامل با Docker Compose

یک اپلیکیشن واقعی تنها نیست؛ معمولاً به پایگاه داده و شاید Redis نیاز دارد. با Docker Compose همه‌ی سرویس‌ها را در یک فایل تعریف می‌کنیم:

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: mysql://app:secret@db:3306/app
    depends_on:
      - db
  db:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: app
      MYSQL_USER: app
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: rootsecret
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:

حالا تنها با دستور docker compose up -d کل پروژه روی هر سیستمی بالا می‌آید. نام سرویس db داخل شبکه‌ی Compose مثل یک نام دامنه عمل می‌کند و نیازی به دانستن IP نیست.

لپ‌تاپ روی میز چوبی کنار گوشی و فنجان قهوه؛ محیط توسعه‌ی آماده برای اجرای Docker Compose

چند نکته‌ی امنیتی و بهینه‌سازی

  • کاربر غیر root: با دستور USER node اگر برنامه آسیب‌پذیر باشد، مهاجم دسترسی کامل به کانتینر نخواهد داشت.
  • ایمیج پایه‌ی کوچک: نسخه‌های alpine یا slim حجم را از حدود یک گیگابایت به کمتر از ۲۰۰ مگابایت می‌رسانند.
  • رمزها داخل ایمیج نباشند: متغیرهای حساس را در زمان اجرا با env_file یا Secrets تزریق کنید.
  • Health Check: یک مسیر ساده مثل /health تعریف کنید تا سرور بداند کانتینر واقعاً سالم است.
  • برچسب نسخه: به‌جای latest از برچسب‌های مشخص مثل node:22-alpine استفاده کنید تا بیلدها قابل پیش‌بینی بمانند.

اسکله و کشتی در مه صبحگاهی؛ کانتینرها آماده‌ی حرکت به سمت سرور

جمع‌بندی

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

دیدگاه‌ها

برای ثبت دیدگاه باید شماره موبایل خود را تأیید کنید.

هنوز دیدگاهی ثبت نشده است. اولین نفر باشید!