Back to Blog
راهنمای کاربردی داکر (Docker) برای توسعه‌دهندگان

راهنمای کاربردی داکر (Docker) برای توسعه‌دهندگان

۱۹ مرداد ۱۴۰۵ FA 10 min read
داکر Docker کانتینرسازی مدیریت وابستگی‌ها DevOps میکروسرویس Angular هوش مصنوعی استقرار نرم‌افزار

اگر چند سالی برنامه‌نویسی کرده باشید، احتمالاً حداقل یک بار با این وضعیت روبه‌رو شدید: پروژه روی سیستم خودتان بدون مشکل اجرا می‌شود، اما همین که روی سیستم یکی از هم‌تیمی‌ها یا روی سرور بالا می‌آید، یک‌دفعه همه‌چیز به هم می‌ریزد.

یک جا نسخه Node.js فرق دارد، جای دیگر نسخه دیتابیس متفاوت است، یک Dependency روی سرور نصب نشده یا تنظیمات Environment با محیط توسعه فرق می‌کند. آخرش هم معمولاً همان جمله معروف را می‌شنویم:

«ولی روی سیستم من کار می‌کرد!»

Docker تا حد زیادی برای حل همین جنس مشکلات ساخته شده است. ایده اصلی آن این است که به جای وابسته بودن اجرای برنامه به تنظیمات یک سیستم مشخص، محیط اجرای نرم‌افزار را هم همراه پروژه تعریف کنیم.

Docker دقیقاً چه مشکلی را حل می‌کند؟

فرض کنید روی یک پروژه وب کار می‌کنیم که از Angular برای Frontend، یک API با Node.js یا .NET، دیتابیس PostgreSQL و Redis استفاده می‌کند.

برای اجرای این پروژه روی یک سیستم جدید، در حالت عادی باید نسخه مناسب تمام این ابزارها نصب شود. بعد Environment Variableها تنظیم شوند، دیتابیس ساخته شود، پورت‌ها بررسی شوند و سرویس‌های مختلف هم به ترتیب اجرا شوند.

در یک تیم چندنفره خیلی زود مشکلات شروع می‌شوند.

ممکن است پروژه با Node.js 22 نوشته شده باشد اما یکی از توسعه‌دهندگان Node.js 20 داشته باشد. ممکن است نسخه PostgreSQL روی سیستم توسعه با سرور Production متفاوت باشد یا یک کتابخانه Native روی یک سیستم نصب شده باشد ولی روی سیستم دیگر وجود نداشته باشد.

Docker تلاش می‌کند این وابستگی به سیستم میزبان را کمتر کند.

به جای اینکه بگوییم:

  • Node.js 22 نصب کن
  • PostgreSQL نصب کن
  • Redis را راه‌اندازی کن
  • این Dependencyها را نصب کن
  • این تنظیمات را انجام بده

محیط موردنیاز برنامه را تعریف می‌کنیم و Docker آن محیط را برای ما ایجاد می‌کند.

ChatGPT Image Aug 10, 2026, 03_54_28 PM

Docker چیست؟

Docker یک پلتفرم برای ساخت و اجرای نرم‌افزار داخل محیط‌هایی به نام Container است.

Container را می‌توان یک محیط ایزوله برای اجرای برنامه در نظر گرفت. برنامه داخل این محیط Runtime، Dependencyها و تنظیمات موردنیاز خودش را دارد و تا حد زیادی از محیط اصلی سیستم جدا است.

فرض کنید Backend پروژه ما برای اجرا به موارد زیر نیاز دارد:

Node.js 22
npm packages
Environment Variables
Port 3000

به جای نصب و تنظیم دستی این موارد روی هر سیستم، آن‌ها را داخل تنظیمات Docker مشخص می‌کنیم.

در نتیجه هر کسی که Docker داشته باشد می‌تواند تقریباً همان محیط را روی سیستم خودش ایجاد کند.

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

Dockerfile چیست؟

برای مشخص کردن نحوه ساخت محیط برنامه معمولاً از فایلی به نام Dockerfile استفاده می‌کنیم.

برای مثال یک Dockerfile ساده برای Backend نوشته‌شده با Node.js می‌تواند چیزی شبیه این باشد:

FROM node:22-alpine

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

در خط اول:

FROM node:22-alpine

مشخص می‌کنیم محیط پایه ما Node.js نسخه 22 باشد.

سپس با:

WORKDIR /app

دایرکتوری کاری برنامه را داخل Container مشخص می‌کنیم.

این قسمت Dependencyهای پروژه را نصب می‌کند:

COPY package*.json ./
RUN npm ci

و در نهایت مشخص می‌کنیم هنگام اجرای Container چه دستوری اجرا شود:

CMD ["npm", "start"]

بعد از آماده شدن Dockerfile می‌توانیم از آن یک Image بسازیم:

docker build -t my-api .

و بعد برنامه را اجرا کنیم:

docker run -p 3000:3000 my-api

در این مرحله Backend ما داخل یک Container اجرا شده است.

تفاوت Image و Container

دو اصطلاحی که هنگام شروع Docker زیاد با آن‌ها برخورد می‌کنیم Image و Container هستند.

Image را می‌توان یک قالب آماده برای اجرای نرم‌افزار در نظر گرفت.

برای مثال:

node:22-alpine
postgres:17
redis:alpine
nginx:alpine

همگی Docker Image هستند.

اما Container نسخه در حال اجرای یک Image است.

اگر بخواهیم با مفاهیم برنامه‌نویسی مقایسه کنیم، می‌توانیم بگوییم Image شبیه Class و Container شبیه Instance آن است.

از یک Image می‌توان چند Container جداگانه ایجاد کرد.

ChatGPT Image Aug 10, 2026, 03_53_29 PM

برای مثال ممکن است یک Image از Backend داشته باشیم و سه Container از روی آن اجرا کنیم تا درخواست‌های کاربران بین آن‌ها تقسیم شود.

Docker با Virtual Machine چه فرقی دارد؟

ممکن است این سؤال پیش بیاید که اگر Virtual Machine داریم، چرا باید از Docker استفاده کنیم؟

در یک Virtual Machine معمولاً هر ماشین مجازی سیستم‌عامل خودش را دارد. یعنی اگر چند VM روی یک سرور اجرا کنیم، هرکدام بخشی از منابع را برای سیستم‌عامل مستقل خودشان مصرف می‌کنند.

ساختار ساده یک VM چیزی شبیه این است:

Hardware
   ↓
Host OS
   ↓
Hypervisor
   ↓
Guest OS
   ↓
Application

Containerها روش متفاوتی دارند.

آن‌ها معمولاً Kernel سیستم میزبان را به اشتراک می‌گذارند و نیازی نیست هر Container یک سیستم‌عامل کامل مستقل داشته باشد.

Hardware
   ↓
Host OS
   ↓
Docker
   ↓
Containers

به همین دلیل Containerها معمولاً بسیار سریع‌تر ساخته و اجرا می‌شوند و منابع کمتری نسبت به یک VM کامل مصرف می‌کنند.

البته Docker جای Virtual Machine را کاملاً نمی‌گیرد.

در بسیاری از زیرساخت‌های واقعی حتی خود Docker داخل یک VM اجرا می‌شود. بنابراین این دو تکنولوژی بیشتر مکمل یکدیگر هستند تا رقیب مستقیم.

ChatGPT Image Aug 10, 2026, 03_57_11 PM

Docker Compose؛ وقتی پروژه چند سرویس دارد

در یک پروژه واقعی معمولاً فقط یک Container نداریم.

ممکن است پروژه ما از سرویس‌های زیر تشکیل شده باشد:

  • Frontend
  • Backend API
  • PostgreSQL
  • Redis
  • Nginx

می‌توان هرکدام از آن‌ها را با دستور docker run اجرا کرد، اما وقتی تعداد سرویس‌ها زیاد شود مدیریت آن‌ها سخت می‌شود.

اینجاست که Docker Compose وارد می‌شود.

با Docker Compose می‌توانیم سرویس‌های پروژه را داخل یک فایل تعریف کنیم.

برای مثال:

services:

  api:
    build: ./backend
    ports:
      - "3000:3000"
    depends_on:
      - database
      - redis

  database:
    image: postgres:17
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: password
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    image: redis:alpine

volumes:
  postgres-data:

بعد برای اجرای کل محیط پروژه کافی است بنویسیم:

docker compose up -d

و برای متوقف کردن آن:

docker compose down

به جای اجرای دستی PostgreSQL، Redis و Backend، کل محیط با یک دستور بالا می‌آید.

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

Volume چیست و چرا به آن نیاز داریم؟

فرض کنید PostgreSQL داخل یک Container اجرا می‌شود.

اگر Container را حذف کنیم، قطعاً نمی‌خواهیم دیتابیس کاربران هم همراه آن حذف شود.

برای حل این مسئله Docker مفهومی به نام Volume دارد.

Volume محلی برای نگهداری داده‌های Persistent است که مستقل از عمر Container باقی می‌ماند.

برای مثال:

volumes:
  - postgres-data:/var/lib/postgresql/data

در این حالت اطلاعات PostgreSQL داخل Volume نگهداری می‌شود.

حالا حتی اگر Container دیتابیس را حذف کنیم و دوباره بسازیم، داده‌های اصلی همچنان وجود دارند.

Volumeها معمولاً برای مواردی مثل دیتابیس، فایل‌های آپلودشده یا اطلاعاتی که نباید با حذف Container از بین بروند استفاده می‌شوند.

Containerها چطور با هم ارتباط برقرار می‌کنند؟

یکی دیگر از مفاهیم مهم Docker، Network است.

فرض کنید Backend ما باید به PostgreSQL متصل شود.

اگر هر دو سرویس داخل Docker Compose تعریف شده باشند، Docker یک Network داخلی بین آن‌ها ایجاد می‌کند.

مثلاً اگر سرویس دیتابیس این نام را داشته باشد:

database:
  image: postgres:17

Backend می‌تواند به جای استفاده از IPهای دستی، مستقیماً با این آدرس به آن متصل شود:

database:5432

در واقع نام سرویس به Hostname آن تبدیل می‌شود.

این قابلیت باعث می‌شود سرویس‌های مختلف پروژه بدون وابستگی به IP سیستم میزبان با یکدیگر ارتباط داشته باشند.

یک پروژه وب واقعی با Docker

فرض کنیم پروژه ما ساختاری شبیه این داشته باشد:

my-project/
│
├── frontend/
│   └── Angular
│
├── backend/
│   └── Node.js
│
├── nginx/
│   └── nginx.conf
│
└── docker-compose.yml

در این پروژه می‌توانیم برای Frontend و Backend Image جداگانه داشته باشیم.

PostgreSQL و Redis هم در Containerهای مستقل اجرا شوند و Nginx درخواست‌های ورودی کاربران را مدیریت کند.

ساختار کلی سیستم می‌تواند چیزی شبیه این باشد:

ChatGPT Image Aug 10, 2026, 03_58_50 PM

حالا اگر توسعه‌دهنده جدیدی Repository را Clone کند، به جای نصب دستی تمام ابزارها، در یک سناریوی ایده‌آل فقط Environment موردنیاز را تنظیم می‌کند و سپس اجرا می‌کند:

docker compose up -d

بعد از چند لحظه Frontend، Backend، Database و Redis آماده کار هستند.

اینجا مزیت Docker خیلی ملموس‌تر می‌شود.

Docker فقط برای پروژه‌های وب نیست

اگرچه مثال‌های Docker معمولاً حول Backend و Database هستند، استفاده از Container محدود به پروژه‌های وب نیست.

یکی از مثال‌های خوب، پروژه‌های هوش مصنوعی و Machine Learning است.

در این پروژه‌ها معمولاً با مجموعه‌ای از Dependencyهای حساس به نسخه روبه‌رو هستیم:

Python
PyTorch
CUDA
cuDNN
Transformers
NumPy

گاهی تغییر کوچک نسخه یکی از این موارد باعث می‌شود پروژه دیگر اجرا نشود.

Docker کمک می‌کند یک محیط مشخص برای اجرای پروژه AI بسازیم و همان محیط را روی سیستم توسعه، سرور یا ماشین دارای GPU اجرا کنیم.

به همین دلیل بسیاری از پروژه‌ها و ابزارهای حوزه AI هم Docker Image آماده ارائه می‌کنند.

Docker همه مشکلات Deployment را حل نمی‌کند

گاهی Docker طوری معرفی می‌شود که انگار با Container کردن پروژه دیگر Deployment هیچ پیچیدگی‌ای ندارد.

اما Docker فقط بخشی از مسئله را حل می‌کند.

هنوز موارد زیادی وجود دارند که باید برای آن‌ها راه‌حل جداگانه داشته باشیم:

  • مدیریت Secretها
  • Security
  • Monitoring
  • Logging
  • Backup
  • Load Balancing
  • مدیریت سرورها
  • استراتژی Deployment

همچنین در پروژه‌های بزرگ ممکن است با ابزارهایی مثل Kubernetes روبه‌رو شویم.

Docker و Kubernetes هم یک چیز نیستند.

Docker بیشتر روی ساخت و اجرای Containerها تمرکز دارد، در حالی که Kubernetes برای مدیریت تعداد زیادی Container و سرویس روی چندین سرور استفاده می‌شود.

چند دستور کاربردی Docker

برای مشاهده Containerهای در حال اجرا:

docker ps

برای مشاهده تمام Containerها:

docker ps -a

برای مشاهده Imageهای موجود:

docker images

برای دیدن Log یک Container:

docker logs <container-name>

برای ورود به Shell یک Container:

docker exec -it <container-name> sh

برای اجرای سرویس‌های Docker Compose:

docker compose up -d

برای مشاهده Log سرویس‌ها:

docker compose logs -f

و برای متوقف کردن کل پروژه:

docker compose down

برای شروع کار با Docker همین چند دستور بخش زیادی از کارهای روزمره را پوشش می‌دهند.

نتیجه‌گیری

مهم‌ترین مزیت Docker فقط این نیست که برنامه را داخل یک Container اجرا می‌کند.

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

می‌توان مشخص کرد برنامه با چه Runtimeای اجرا شود، چه Dependencyهایی نیاز دارد، چه سرویس‌هایی باید کنار آن باشند و ارتباط بین این سرویس‌ها چگونه انجام شود.

این موضوع باعث می‌شود فاصله بین محیط Development، Testing و Production کمتر شود و راه‌اندازی پروژه روی سیستم‌های مختلف قابل پیش‌بینی‌تر باشد.

در یک پروژه کوچک شاید مزیت Docker خیلی محسوس نباشد، اما وقتی Database، Cache، Backend، Frontend، Worker و سرویس‌های دیگر وارد پروژه شوند، ارزش آن خیلی سریع مشخص می‌شود.

Docker تمام مشکلات توسعه و Deployment را حل نمی‌کند، اما یکی از دردسرهای قدیمی برنامه‌نویسی را تا حد زیادی کاهش می‌دهد:

اینکه نرم‌افزار فقط روی سیستم کسی که آن را نوشته درست اجرا شود.

💙 اگر این مقاله براتون مفید بود، خوشحال می‌شم با لایک کردن و به‌اشتراک‌گذاری اون با بقیه، حمایت کنید.