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

Docker Compose چه مشکلی را حل میکند؟
Docker ابزاری برای ساخت و اجرای برنامهها در محیطهای ایزولهای به نام Container است. هر کانتینر میتواند شامل برنامه و وابستگیهای موردنیاز آن باشد.
برای مثال، فرض کنید یک برنامه تحت وب با Python نوشتهاید و اطلاعات آن در پایگاه داده PostgreSQL ذخیره میشود. در این شرایط حداقل به دو کانتینر نیاز دارید:
- کانتینر اول برای اجرای برنامه وب
- کانتینر دوم برای اجرای پایگاه داده
اگر بخواهید این کانتینرها را جداگانه اجرا کنید، باید تنظیمات مربوط به پورتها، متغیرهای محیطی، شبکه و ارتباط میان آنها را مدیریت کنید.
Docker Compose این تنظیمات را در یک فایل متمرکز میکند. در نتیجه میتوانید سرویسهای پروژه را با یک دستور اجرا کنید و با دستورات دیگری وضعیت آنها را بررسی یا متوقف کنید.
تفاوت Dockerfile و Docker Compose چیست؟
این دو ابزار با یکدیگر ارتباط دارند، اما وظایف متفاوتی انجام میدهند.
| ویژگی | Dockerfile | Docker Compose |
|---|---|---|
| وظیفه اصلی | تعریف مراحل ساخت Image | تعریف و مدیریت سرویسها |
| محل تنظیمات | فایل Dockerfile | فایل compose.yaml |
| کاربرد | آمادهسازی محیط اجرای برنامه | اجرای هماهنگ چند سرویس |
| خروجی اصلی | Docker Image | مجموعه سرویسهای تعریفشده برای پروژه |
به زبان ساده، Dockerfile مشخص میکند Image برنامه چگونه ساخته شود؛ اما Docker Compose مشخص میکند سرویسهای پروژه چگونه در کنار یکدیگر اجرا شوند.
برای آشنایی بیشتر با مفاهیم پایه میتوانید به مستندات رسمی Docker مراجعه کنید.
پیشنیازهای اجرای پروژه با Docker Compose
برای کار با Docker و مدیریت پروژههای چندکانتینری، آشنایی با محیط خط فرمان و دستورات پایه سیستمعامل اهمیت زیادی دارد. بسیاری از مراحل اجرای پروژه، بررسی وضعیت کانتینرها و مشاهده گزارش خطاها از طریق ترمینال انجام میشوند. اگر هنوز با محیط لینوکس و دستورات پرکاربرد آن آشنایی کافی ندارید، یادگیری این مباحث میتواند شروع مناسبی برای ورود به دنیای ابزارهای توسعه و استقرار نرمافزار باشد. در این مسیر میتوانید از دوره لینوکس از پایه نیز بهعنوان منبع تکمیلی استفاده کنید.
قبل از شروع پروژه باید ابزارهای موردنیاز را روی سیستم نصب داشته باشید.
۱. نصب Docker
در ویندوز و مک میتوانید از Docker Desktop استفاده کنید. کاربران لینوکس نیز میتوانند Docker Engine و افزونه Docker Compose را نصب کنند.
صفحه رسمی دریافت و نصب Docker:
https://docs.docker.com/get-started/get-docker/
۲. بررسی نصب Docker
ترمینال یا PowerShell را باز کنید و دستور زیر را اجرا کنید:
docker --versionبرای بررسی Docker Compose نیز دستور زیر را وارد کنید:
docker compose versionاگر نسخه ابزارها نمایش داده شود، میتوانید مراحل بعدی را انجام دهید.
۳. آشنایی مقدماتی با ترمینال
برای اجرای دستورات پروژه باید بتوانید میان پوشهها جابهجا شوید، فایل ایجاد کنید و دستورات موردنیاز را اجرا کنید.
ساختار فایل Docker Compose چگونه است؟
Docker Compose از یک فایل YAML برای تعریف سرویسهای پروژه استفاده میکند. نام رایج این فایل در نسخههای جدید compose.yaml است.
یک ساختار ساده میتواند به شکل زیر باشد:
services:
web:
build: .
ports:
- "8000:5000"
db:
image: postgres:17در این مثال دو سرویس با نامهای web و db تعریف شدهاند.
هر سرویس میتواند تنظیمات مستقلی داشته باشد.
اگر میخواهید یک نمونه ساده را مرحلهبهمرحله اجرا کنید، راهنمای شروع کار با Docker Compose در مستندات رسمی Docker میتواند مرجع مناسبی برای آشنایی با فرایند اولیه باشد.
بخشهای مهم فایل Compose
services: برای تعریف سرویسهای مختلف پروژه استفاده میشود. هر سرویس معمولاً با یک کانتینر یا مجموعهای از کانتینرهای مرتبط اجرا میشود.
image: مشخص میکند سرویس از کدام Image استفاده کند.
build: مسیر ساخت Image از طریق Dockerfile را مشخص میکند.
ports: برای اتصال پورت کانتینر به پورت سیستم میزبان استفاده میشود.
برای مثال:
ports:
- "8000:5000"یعنی پورت ۵۰۰۰ داخل کانتینر از طریق پورت ۸۰۰۰ سیستم میزبان در دسترس قرار میگیرد.
environment: متغیرهای محیطی موردنیاز برنامه را تعریف میکند.
volumes: برای نگهداری اطلاعات خارج از چرخه عمر کانتینر و اتصال فضای ذخیرهسازی به سرویس استفاده میشود.
networks: ارتباط شبکهای میان سرویسها را مدیریت میکند.
برای بررسی گزینههای پیکربندی و ویژگیهای قابل استفاده در فایل پروژه، میتوانید از مرجع رسمی ساختار فایل Compose استفاده کنید.
اجرای یک پروژه چندکانتینری با Docker Compose
حالا یک پروژه ساده ایجاد میکنیم که شامل دو سرویس است:
- برنامه وب با Python و Flask
- پایگاه داده PostgreSQL
هدف این است که برنامه بتواند به پایگاه داده متصل شود و اطلاعات موردنیاز را دریافت کند.

مرحله اول: ایجاد پوشه پروژه
ابتدا یک پوشه با نام دلخواه ایجاد کنید. برای مثال:
mkdir docker-compose-project
cd docker-compose-projectساختار فایلهای پروژه به شکل زیر خواهد بود:
docker-compose-project/
│
├── app.py
├── requirements.txt
├── Dockerfile
├── compose.yaml
├── .env
└── .dockerignoreهر فایل وظیفه مشخصی دارد:
app.py: کد برنامه وبrequirements.txt: وابستگیهای PythonDockerfile: دستورالعمل ساخت Image برنامهcompose.yaml: تنظیمات سرویسهای پروژه.env: مقادیر متغیرهای محیطی.dockerignore: فایلهایی که نباید وارد فرایند ساخت Image شوند.
مرحله دوم: ایجاد برنامه Python
فایل app.py را ایجاد کنید و کد زیر را داخل آن قرار دهید:
import os
import psycopg
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
with psycopg.connect(
host=os.getenv("DB_HOST", "db"),
dbname=os.getenv("DB_NAME"),
user=os.getenv("DB_USER"),
password=os.getenv("DB_PASSWORD"),
port=5432,
connect_timeout=3
) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT version()")
version = cursor.fetchone()[0]
return f"""
<h1>Docker Compose Project</h1>
<p>Connection to PostgreSQL successful.</p>
<p>{version}</p>
"""
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)این برنامه با استفاده از Flask یک صفحه وب ساده ایجاد میکند.
هنگام بازشدن صفحه، برنامه به PostgreSQL متصل میشود و نسخه پایگاه داده را نمایش میدهد.
نکته مهم این است که آدرس میزبان پایگاه داده در برنامه db در نظر گرفته شده است. این نام همان نام سرویس PostgreSQL در فایل Compose خواهد بود.
مرحله سوم: تعریف وابستگیهای برنامه
فایل requirements.txt را ایجاد کنید:
Flask>=3.1,<4
psycopg[binary]>=3.2,<4این فایل مشخص میکند برنامه به چه کتابخانههایی نیاز دارد.
Flask برای ایجاد برنامه وب و Psycopg برای برقراری ارتباط با PostgreSQL استفاده میشود.
مرحله چهارم: ایجاد Dockerfile
حالا باید مشخص کنیم Image برنامه چگونه ساخته شود.
فایل Dockerfile را با محتوای زیر ایجاد کنید:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]توضیح دستورها:
FROM: Image پایه موردنیاز را مشخص میکند.WORKDIR: پوشه کاری داخل کانتینر را تعیین میکند.COPY: فایلهای پروژه را به کانتینر منتقل میکند.RUN: دستور نصب کتابخانهها را اجرا میکند.EXPOSE: پورت مورد استفاده برنامه را مستند میکند.CMD: فرمان پیشفرض اجرای برنامه را تعیین میکند.
این Dockerfile برای یک نمونه ساده توسعهای نوشته شده است. برای استقرار واقعی و محیط Production باید سرور اجرایی مناسب، تنظیمات امنیتی و مدیریت فرایند اجرا نیز در نظر گرفته شوند.
مرحله پنجم: تنظیم متغیرهای محیطی
برای اینکه اطلاعات اتصال پایگاه داده مستقیماً داخل فایل اصلی Compose نوشته نشوند، از فایل .env استفاده میکنیم.
محتوای نمونه:
POSTGRES_DB=sampledb
POSTGRES_USER=sampleuser
POSTGRES_PASSWORD=change_this_local_passwordاین مقادیر برای محیط تمرینی هستند. رمز عبور واقعی و حساس نباید در مخزن عمومی Git قرار بگیرد.
فایل .env به Docker Compose کمک میکند مقادیر متغیرها را هنگام خواندن فایل Compose جایگذاری کند.
مرحله ششم: نوشتن فایل compose.yaml
حالا مهمترین بخش پروژه را ایجاد میکنیم.
محتوای فایل compose.yaml:
services:
web:
build: .
ports:
- "8000:5000"
environment:
DB_HOST: db
DB_NAME: ${POSTGRES_DB:-sampledb}
DB_USER: ${POSTGRES_USER:-sampleuser}
DB_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
environment:
POSTGRES_DB: ${POSTGRES_DB:-sampledb}
POSTGRES_USER: ${POSTGRES_USER:-sampleuser}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test:
- CMD-SHELL
- pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
volumes:
postgres_data:در این فایل دو سرویس تعریف شدهاند.
سرویس web
این سرویس برنامه Python را اجرا میکند. دستور build: . باعث میشود Docker از Dockerfile موجود در پوشه پروژه برای ساخت Image استفاده کند.
همچنین پورت ۵۰۰۰ کانتینر به پورت ۸۰۰۰ سیستم میزبان متصل شده است.
سرویس db
این سرویس از Image رسمی PostgreSQL استفاده میکند و متغیرهای محیطی لازم برای ساخت پایگاه داده را دریافت میکند.
بخش depends_on
در این مثال از شرط service_healthy استفاده شده است. بنابراین سرویس وب پس از سالمشدن وضعیت پایگاه داده شروع به اجرا میکند.
بخش healthcheck
دستور pg_isready بررسی میکند که PostgreSQL آماده دریافت اتصال باشد.
بخش volumes
یک Volume با نام postgres_data تعریف شده تا اطلاعات پایگاه داده با حذف کانتینر از بین نروند.
نکته: این فایل از قابلیتهای استاندارد Docker Compose استفاده میکند. جزئیات بیشتر در مستندات رسمی فایل Compose موجود است.
مرحله هفتم: جلوگیری از ورود فایلهای غیرضروری
برای جلوگیری از کپیشدن فایلهای غیرضروری به Image، فایل .dockerignore را ایجاد کنید:
.env
.git
__pycache__
*.pyc
.venv
venvاین کار باعث میشود فایلهای محیطی و برخی فایلهای موقت وارد فرایند ساخت Image نشوند.
مرحله هشتم: اجرای پروژه با Docker Compose
پس از آمادهشدن فایلها، ترمینال را در پوشه اصلی پروژه باز کنید و دستور زیر را اجرا کنید:
docker compose up -d --buildاین دستور چند کار انجام میدهد:
- فایل Compose را میخواند.
- Image برنامه را میسازد.
- Image موردنیاز PostgreSQL را دریافت میکند.
- کانتینرهای پروژه را ایجاد میکند.
- سرویس پایگاه داده را اجرا میکند.
- پس از آمادهشدن پایگاه داده، سرویس وب را اجرا میکند.
گزینه -d باعث میشود کانتینرها در پسزمینه اجرا شوند.
برای مشاهده وضعیت سرویسها از دستور زیر استفاده کنید:
docker compose psاگر سرویسها بدون خطا اجرا شده باشند، میتوانید مرورگر را باز کنید و به آدرس زیر بروید:
http://localhost:8000در صورت موفقیت اتصال، صفحه برنامه نمایش داده میشود و اطلاعات نسخه PostgreSQL را مشاهده میکنید.
مدیریت سرویسها در Docker Compose
پس از اجرای پروژه، لازم است بتوانید وضعیت سرویسها را بررسی و در صورت نیاز آنها را مدیریت کنید.
مشاهده گزارشهای اجرای برنامه
برای مشاهده گزارشهای همه سرویسها:
docker compose logsبرای مشاهده زنده گزارشها:
docker compose logs -fاگر فقط گزارش سرویس وب را میخواهید:
docker compose logs webبررسی وضعیت کانتینرها
docker compose psاین دستور وضعیت سرویسهای پروژه را نمایش میدهد.
اجرای دستور داخل یک کانتینر
در یک پروژه واقعی، معمولاً برنامه سمت سرور وظیفه پردازش درخواستها و ارتباط با پایگاه داده را بر عهده دارد. شناخت ساختار بکاند و نحوه ارتباط اجزای مختلف یک برنامه به درک بهتر معماری پروژههای چندکانتینری کمک میکند. اگر میخواهید با مفاهیم توسعه سمت سرور و ساختار برنامههای بکاند بیشتر آشنا شوید، میتوانید مباحث مرتبط را در دوره بکاند پرتقال دنبال کنید.
برای ورود به محیط تعاملی کانتینر برنامه میتوانید از دستور زیر استفاده کنید:
docker compose exec web shبرای اتصال به محیط PostgreSQL:
docker compose exec db psql -U sampleuser -d sampledbدر این مثال نام کاربری و پایگاه داده با مقادیر فایل .env هماهنگ هستند.
توقف پروژه
برای متوقفکردن سرویسها بدون حذف آنها:
docker compose stopبرای اجرای دوباره:
docker compose startاگر بخواهید کانتینرها و شبکه ایجادشده توسط پروژه حذف شوند:
docker compose downتوجه داشته باشید که دستور down بهتنهایی Volume نامگذاریشده پروژه را حذف نمیکند.
برای حذف Volumeها نیز باید از گزینه -v استفاده کنید:
docker compose down -vاین دستور اطلاعات ذخیرهشده در Volume را نیز حذف میکند؛ بنابراین در پروژههای واقعی باید با دقت استفاده شود.
نقش Volume و Network در Docker Compose
دو مفهوم مهم در اجرای پروژههای چندکانتینری، Volume و Network هستند.

Volume چیست؟
اطلاعاتی که مستقیماً در لایه نوشتنی کانتینر ذخیره میشوند، با حذف کانتینر از بین میروند.
برای جلوگیری از این مشکل، Docker از Volume استفاده میکند.
در پروژه ما:
volumes:
- postgres_data:/var/lib/postgresql/dataاین تنظیم باعث میشود اطلاعات پایگاه داده در Volume مستقلی ذخیره شوند.
در نتیجه، با توقف یا حذف کانتینر PostgreSQL، دادهها همچنان باقی میمانند؛ مگر اینکه خود Volume نیز حذف شود.
برای نگهداری اطلاعاتی که نباید با حذف یا بازسازی کانتینر از بین بروند، میتوان از Volume استفاده کرد. جزئیات این روش در مستندات رسمی Docker Volumes آمده است.
Network چیست؟
Docker Compose بهصورت پیشفرض برای پروژه یک شبکه ایجاد میکند و سرویسهای آن را به این شبکه متصل میکند.
به همین دلیل برنامه وب میتواند از طریق نام سرویس db به پایگاه داده متصل شود.
برای مثال:
host="db"در این حالت نیازی نیست IP داخلی کانتینر پایگاه داده را بهصورت دستی پیدا کنید.
این ویژگی مدیریت ارتباط میان سرویسها را سادهتر میکند.
Docker Compose امکان ارتباط میان سرویسهای یک پروژه را از طریق شبکه فراهم میکند. جزئیات این قابلیت و روش پیکربندی آن در مستندات شبکهسازی در Docker Compose توضیح داده شده است.
خطاهای رایج هنگام اجرای Docker Compose
در زمان راهاندازی پروژه ممکن است با مشکلات مختلفی روبهرو شوید. چند مورد رایج عبارتاند از:
| خطا | علت احتمالی | راهکار |
|---|---|---|
| اشغال بودن پورت | برنامه دیگری از پورت ۸۰۰۰ استفاده میکند | تغییر پورت سمت میزبان |
| خطای اتصال به پایگاه داده | سرویس DB آماده نیست یا تنظیمات اتصال اشتباه است | بررسی وضعیت سرویس و متغیرهای محیطی |
| خطای ساخت Image | مشکل در Dockerfile یا دریافت وابستگیها | بررسی مراحل Build و گزارش خطا |
| خطای YAML | اشتباه در تورفتگی یا ساختار فایل | بررسی فاصلهها و ساختار فایل |
| باقیماندن اطلاعات قدیمی | استفاده از Volume قبلی | بررسی Volume و دادههای ذخیرهشده |
بررسی صحت فایل Compose
یکی از دستورات کاربردی برای بررسی ساختار و تنظیمات فایل Compose:
docker compose configاین دستور تنظیمات نهایی Compose را نمایش میدهد و میتواند به شناسایی برخی خطاهای ساختاری و متغیرهای تعریفنشده کمک کند.
برای بررسی خطاهای زمان اجرا نیز از دستور زیر استفاده کنید:
docker compose logs -fبهتر است پیش از حذف کانتینرها یا Volumeها، علت خطا را از گزارشها پیدا کنید.
نکات امنیتی هنگام استفاده از Docker Compose
استفاده از Docker Compose بهتنهایی امنیت یک پروژه را تضمین نمیکند. برای کاهش ریسک باید چند نکته را رعایت کنید:
- رمز عبور پایگاه داده را در مخزن عمومی Git قرار ندهید.
- فایل
.envرا به.gitignoreاضافه کنید. - برای محیطهای حساس از روشهای مدیریت امن اطلاعات محرمانه مانند Docker Secrets استفاده کنید.
- Imageهای مورد استفاده را از منابع معتبر دریافت کنید.
- از انتشار غیرضروری پورت پایگاه داده روی سیستم میزبان خودداری کنید.
- در محیط Production از تنظیمات مناسب برای سرور برنامه، دسترسیها و پشتیبانگیری استفاده کنید.
برای اطلاعات بیشتر میتوانید راهنمای بهترین روشهای مدیریت متغیرهای محیطی در Docker Compose را مطالعه کنید.
سؤالات متداول درباره Docker Compose
_آیا Docker Compose همراه Docker نصب میشود؟
در Docker Desktop، Compose بهصورت یکپارچه ارائه میشود. در محیطهای لینوکس ممکن است لازم باشد افزونه Compose را جداگانه نصب کنید.
_آیا برای اجرای پروژه با Docker Compose حتماً به Dockerfile نیاز داریم؟
خیر. اگر از Image آماده استفاده کنید، میتوانید آن را مستقیماً در بخش image تعریف کنید. Dockerfile زمانی موردنیاز است که بخواهید Image اختصاصی برنامه خود را بسازید.
_تفاوت docker compose و docker-compose چیست؟
docker compose شکل جدید دستور Compose بهعنوان افزونه Docker CLI است. docker-compose به ابزار مستقل و قدیمیتر Compose اشاره دارد که در پروژههای قدیمیتر دیده میشود.
_آیا با حذف کانتینر، اطلاعات پایگاه داده هم حذف میشود؟
اگر اطلاعات در لایه نوشتنی کانتینر ذخیره شده باشند، با حذف کانتینر از بین میروند. اما اگر از Volume استفاده کنید، اطلاعات مستقل از چرخه عمر کانتینر باقی میمانند؛ مگر اینکه Volume نیز حذف شود.
_آیا Docker Compose برای محیط Production مناسب است؟
Docker Compose در بسیاری از سناریوها برای اجرای برنامههای چندکانتینری کاربرد دارد؛ اما استفاده از آن در Production نیازمند بررسی امنیت، پشتیبانگیری، مدیریت منابع، مانیتورینگ و تنظیمات استقرار مناسب است.
جمعبندی
Docker Compose مدیریت پروژههایی را که از چند سرویس وابسته به هم تشکیل شدهاند سادهتر میکند. با تعریف سرویسها در فایل compose.yaml میتوان برنامه، پایگاه داده و سایر اجزای پروژه را در یک ساختار منظم مدیریت کرد.
در مثال این مقاله، یک برنامه Python Flask را در کنار PostgreSQL اجرا کردیم و با مفاهیمی مانند سرویس، Volume، Network، متغیرهای محیطی و دستورات مدیریت کانتینرها آشنا شدیم.
مزیت اصلی Docker Compose این است که تنظیمات اجرای پروژه در یک فایل متمرکز میشوند و راهاندازی مجدد محیط توسعه یا انتقال تنظیمات پروژه به سیستم دیگر سادهتر خواهد شد. با شناخت این ابزار میتوانید بهجای مدیریت جداگانه کانتینرها، اجزای پروژه را بهصورت هماهنگ مدیریت کنید.




