Docker Compose چیست؟ راهنمای اجرای اپلیکیشن‌های چند-کانتینری
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 16 دقیقه

Docker Compose چیست؟ راهنمای اجرای اپلیکیشن‌های چند-کانتینری

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

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

Compose نه‌فقط اجرای چند کانتینر را ساده می‌کند، بلکه یک لایه انتزاعی روی Docker می‌سازد تا توسعه‌دهنده بتواند روی منطق اپلیکیشن تمرکز کند، نه روی مدیریت زیرساخت.

Docker Compose چیست؟

Docker Compose ابزاری است که برای تعریف، مدیریت و اجرای مجموعه‌ای از کانتینرها در کنار هم طراحی شده است، مجموعه‌ای که معمولا یک اپلیکیشن کامل را تشکیل می‌دهد. در معماری‌های امروزی، یک پروژه به‌جای یک سرویس واحد، از چندین جز تشکیل می‌شود: یک سرویس وب، یک دیتابیس، یک کش، یک پیام‌رسان، یک سرویس لاگ یا مانیتورینگ و… . هرکدام از این سرویس‌ها باید در کانتینر جداگانه اجرا شوند، اما در نهایت باید مثل یک سیستم یکپارچه با هم کار کنند. Compose این هماهنگی را ساده، قابل‌تکرار و استاندارد می‌کند.

Compose در اصل یک «تعریف زیرساخت» است که در قالب یک فایل YAML نوشته می‌شود. این فایل مشخص می‌کند هر سرویس از چه ایمیجی ساخته شود، چه پورت‌هایی باز کند، چه ولوم‌هایی نیاز دارد، به چه شبکه‌ای وصل شود و به چه سرویس‌هایی وابسته است. به‌جای اجرای چندین دستور Docker برای هر سرویس، تنها کافی است یک دستور اجرا شود تا کل اپلیکیشن بالا بیاید.

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

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

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

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

معماری و اجزای Docker Compose

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

۱) سرویس‌ها (Services)

سرویس‌ها هسته اصلی هر فایل Compose هستند. هر سرویس نماینده یک کانتینر یا مجموعه‌ای از کانتینرهاست که یک نقش مشخص در اپلیکیشن ایفا می‌کنند. برای مثال، یک سرویس می‌تواند وب‌سرور باشد، سرویس دیگر دیتابیس، و سرویس دیگر کش.

در تعریف هر سرویس معمولا موارد زیر مشخص می‌شود:

  • ایمیج مورد استفاده یا مسیر بیلد
  • پورت‌های قابل دسترس
  • ولوم‌های مورد نیاز
  • متغیرهای محیطی
  • شبکه‌ای که سرویس باید به آن متصل شود
  • وابستگی‌ها به سایر سرویس‌ها

Compose با استفاده از این تعریف‌ها، سرویس‌ها را به‌صورت هماهنگ و با ترتیب صحیح اجرا می‌کند.

۲) شبکه‌ها (Networks)

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

ویژگی‌های کلیدی شبکه‌ها:

  • ایجاد شبکه‌های اختصاصی برای هر پروژه
  • امکان تعریف شبکه‌های سفارشی
  • جداسازی ترافیک بین سرویس‌ها
  • دسترسی سرویس‌ها به یکدیگر از طریق DNS داخلی Compose

۳) ولوم‌ها (Volumes)

ولوم‌ها برای ذخیره‌سازی داده‌های پایدار استفاده می‌شوند. در محیط‌های چندکانتینری، سرویس‌هایی مانند دیتابیس نیاز دارند داده‌ها حتی پس از توقف کانتینر باقی بماند. Compose امکان تعریف ولوم‌های مشترک یا اختصاصی را فراهم می‌کند.

کاربردهای رایج ولوم‌ها:

  • ذخیره‌سازی داده‌های دیتابیس
  • نگهداری فایل‌های لاگ
  • اشتراک‌گذاری فایل‌ها بین سرویس‌ها
  • جلوگیری از حذف داده‌ها هنگام بازسازی کانتینرها

۴) ایمیج‌ها و بیلد (Images & Build)

Compose می‌تواند از ایمیج‌های آماده استفاده کند یا ایمیج‌ها را از طریق Dockerfile بسازد. این انعطاف‌پذیری باعث می‌شود بتوان پروژه را به‌صورت کامل در یک فایل تعریف کرد.

دو حالت اصلی وجود دارد:

  • استفاده از ایمیج‌های موجود در رجیستری
  • ساخت ایمیج از مسیر پروژه با استفاده از دستور build

این قابلیت به‌ویژه در محیط توسعه اهمیت دارد، زیرا تغییرات کد به‌سرعت در ایمیج جدید اعمال می‌شود.

۵) متغیرهای محیطی (Environment Variables)

Compose امکان تعریف متغیرهای محیطی برای هر سرویس را فراهم می‌کند. این متغیرها معمولا برای تنظیمات حساس یا پارامترهای قابل‌تغییر استفاده می‌شوند.

روش‌های رایج استفاده:

  • تعریف مستقیم در فایل Compose
  • استفاده از فایل env.
  • استفاده از مقادیر پیش‌فرض

این ساختار باعث می‌شود تنظیمات پروژه قابل‌مدیریت و قابل‌انتقال باشد.

۶) وابستگی سرویس‌ها (depends_on)

در بسیاری از پروژه‌ها، سرویس‌ها باید با ترتیب مشخصی اجرا شوند. برای مثال، سرویس وب باید پس از دیتابیس بالا بیاید. Compose با استفاده از گزینه depends_on این وابستگی‌ها را مدیریت می‌کند.

این قابلیت تضمین می‌کند:

  • سرویس‌ها با ترتیب صحیح اجرا شوند
  • خطاهای ناشی از عدم آماده‌بودن سرویس‌های زیرساختی کاهش یابد

۷) پروفایل‌ها (Profiles)

Compose امکان تعریف پروفایل‌های مختلف را فراهم می‌کند تا بتوان سرویس‌ها را بر اساس نیاز فعال یا غیرفعال کرد. این ویژگی برای محیط‌های توسعه، تست و استیجینگ بسیار کاربردی است.

نمونه کاربرد:

  • اجرای سرویس‌های مانیتورینگ فقط در محیط توسعه
  • فعال‌کردن سرویس‌های اضافی برای تست بار

۸) موتور اجرای Compose

Compose از طریق یک CLI واحد مدیریت می‌شود. این CLI با Docker Engine تعامل دارد و سرویس‌ها را بر اساس تعریف YAML اجرا می‌کند. نتیجه این است که توسعه‌دهنده بدون نیاز به اجرای چندین دستور پیچیده، تنها با یک دستور کل اپلیکیشن را مدیریت می‌کند.

ساختار فایل docker-compose.yml

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

۱) تعریف سرویس‌ها (services)

بخش services جایی است که هر سرویس اپلیکیشن تعریف می‌شود. هر سرویس در نهایت تبدیل به یک کانتینر می‌شود.

نمونه:

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - APP_ENV=development
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - db_data:/var/lib/postgresql/data

نکات عملی:

  • سرویس web از Dockerfile پروژه ساخته می‌شود.
  • سرویس db از یک ایمیج آماده استفاده می‌کند.
  • سرویس web تا زمانی که db آماده نباشد اجرا نمی‌شود.
  • داده‌های دیتابیس در ولوم ذخیره می‌شود تا با حذف کانتینر از بین نرود.

۲) پورت‌ها (ports)

پورت‌ها برای دسترسی به سرویس‌ها از خارج کانتینر استفاده می‌شوند.

ports:
  - "8000:8000"

در این مثال:

  • پورت 8000 روی سیستم میزبان
  • به پورت 8000 داخل کانتینر متصل می‌شود

این نگاشت برای سرویس‌های وب ضروری است.

۳) ولوم‌ها (volumes)

همانطور که گفته شد، ولوم‌ها برای ذخیره‌سازی داده‌های پایدار استفاده می‌شوند.

تعریف در سطح سرویس:

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

تعریف در سطح بالا:

volumes:
  db_data:

نکات عملی:

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

۴) شبکه‌ها (networks)

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

نمونه عملی:

services:
  web:
    networks:
      - backend

  db:
    networks:
      - backend

networks:
  backend:
    driver: bridge

کاربرد عملی:

  • جداسازی سرویس‌ها در شبکه‌های مختلف
  • افزایش امنیت
  • کنترل بهتر روی ارتباطات داخلی

۵) متغیرهای محیطی (environment و env_file)

برای مدیریت تنظیمات قابل‌تغییر، از متغیرهای محیطی استفاده می‌شود.

تعریف مستقیم:

environment:
  - APP_ENV=development

استفاده از فایل env.:

env_file:
  - .env

این روش برای پروژه‌های واقعی توصیه می‌شود، زیرا:

  • فایل Compose تمیزتر می‌ماند
  • اطلاعات حساس در فایل جداگانه نگهداری می‌شود

۶) وابستگی سرویس‌ها (depends_on)

برای اجرای سرویس‌ها با ترتیب مشخص:

depends_on:
  - db

نکته مهم:

  • این گزینه فقط ترتیب اجرا را تضمین می‌کند، نه آماده‌بودن سرویس
  • برای اطمینان از آماده‌بودن سرویس‌ها باید از healthcheck استفاده شود

نمونه:

db:
  image: postgres:15
  healthcheck:
    test: ["CMD", "pg_isready", "-U", "user"]
    interval: 5s
    retries: 5

۷) پروفایل‌ها (profiles)

برای فعال‌سازی سرویس‌های خاص در محیط‌های مختلف:

services:
  monitoring:
    image: grafana/grafana
    profiles:
      - dev

اجرای Compose با پروفایل dev:

docker compose --profile dev up

کاربرد عملی:

  • اجرای سرویس‌های اضافی فقط در محیط توسعه
  • کاهش مصرف منابع در محیط‌های سبک

۸) ساختار کامل یک فایل Compose عملی

در نهایت، یک نمونه کاربردی و قابل‌استفاده:

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - APP_ENV=development
    depends_on:
      - db
    networks:
      - backend

  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - backend

volumes:
  db_data:

networks:
  backend:
    driver: bridge

این ساختار برای یک پروژه واقعی کاملا قابل‌استفاده است و پایه‌ای برای توسعه پروژه‌های پیچیده‌تر محسوب می‌شود.

یک مثال ساده: اجرای یک اپلیکیشن وب + دیتابیس

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

۱) ساختار پروژه

برای شروع، یک ساختار ساده در نظر می‌گیریم:

project/
│
├── app/
│   ├── Dockerfile
│   └── app.py
│
└── docker-compose.yml

در این مثال، سرویس وب یک برنامه ساده است (مثلاً Python یا Node.js) و سرویس دیتابیس از PostgreSQL استفاده می‌کند.

۲) تعریف سرویس وب

سرویس وب از Dockerfile موجود در پوشه app ساخته می‌شود. این سرویس باید پورت خود را در دسترس قرار دهد و به دیتابیس متصل شود.

نمونه عملی:

services:
  web:
    build: ./app
    ports:
      - "8000:8000"
    environment:
      - DB_HOST=db
      - DB_USER=user
      - DB_PASS=pass
    depends_on:
      - db

نکات کلیدی:

  • سرویس web از مسیر app بیلد می‌شود.
  • پورت 8000 برای دسترسی از میزبان باز می‌شود.
  • نام سرویس db به‌عنوان میزبان دیتابیس استفاده می‌شود.
  • وابستگی به سرویس db تضمین می‌کند که دیتابیس قبل از وب‌سرور اجرا شود.

۳) تعریف سرویس دیتابیس

سرویس دیتابیس از یک ایمیج آماده PostgreSQL استفاده می‌کند و داده‌ها را در یک ولوم پایدار ذخیره می‌کند.

  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - db_data:/var/lib/postgresql/data

نکات عملی:

  • داده‌ها در ولوم db_data ذخیره می‌شوند.
  • با حذف کانتینر، داده‌ها از بین نمی‌روند.
  • متغیرهای محیطی برای ایجاد دیتابیس اولیه استفاده می‌شوند.

۴) تعریف ولوم‌ها

در انتهای فایل Compose، ولوم‌ها تعریف می‌شوند:

volumes:
  db_data:

این تعریف باعث می‌شود ولوم db_data به‌صورت پایدار و مستقل از کانتینرها ایجاد شود.

۵) فایل Compose کامل

در نهایت، فایل کامل به شکل زیر خواهد بود:

services:
  web:
    build: ./app
    ports:
      - "8000:8000"
    environment:
      - DB_HOST=db
      - DB_USER=user
      - DB_PASS=pass
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

این فایل یک محیط کامل شامل وب‌سرور و دیتابیس را تنها با یک دستور اجرا می‌کند.

۶) اجرای پروژه

برای اجرای پروژه:

docker compose up

برای اجرای پروژه در پس‌زمینه:

docker compose up -d

برای توقف سرویس‌ها:

docker compose down

برای حذف ولوم‌ها (در صورت نیاز):

docker compose down -v

۷) نتیجه نهایی

با اجرای این فایل Compose:

  • سرویس وب و دیتابیس به‌صورت هماهنگ اجرا می‌شوند
  • ارتباط بین سرویس‌ها از طریق شبکه داخلی Compose برقرار می‌شود
  • داده‌های دیتابیس پایدار باقی می‌مانند
  • کل محیط تنها با یک دستور قابل راه‌اندازی و توقف است

این الگو پایه‌ای‌ترین و در عین حال رایج‌ترین سناریوی استفاده از Docker Compose در پروژه‌های واقعی است.

مدیریت چرخه حیات سرویس‌ها در Docker Compose

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

برای اجرای تمام سرویس‌های تعریف‌شده در فایل Compose:

docker compose up

اجرای سرویس‌ها در پس‌زمینه:

docker compose up -d

نکات عملی:

  • در حالت عادی، لاگ‌ها در همان ترمینال نمایش داده می‌شوند.
  • در حالت پس‌زمینه، سرویس‌ها بدون اشغال ترمینال اجرا می‌شوند.

برای توقف سرویس‌ها بدون حذف کانتینرها:

docker compose stop

برای توقف و حذف کانتینرها:

docker compose down

برای حذف کانتینرها همراه با ولوم‌ها:

docker compose down -v

این دستور زمانی کاربرد دارد که بخواهید دیتابیس یا داده‌های ذخیره‌شده را از ابتدا بسازید.

برای مشاهده لاگ‌های تمام سرویس‌ها:

docker compose logs

برای دنبال‌کردن لحظه‌ای لاگ‌ها:

docker compose logs -f

برای مشاهده لاگ‌های یک سرویس خاص:

docker compose logs web

این قابلیت برای دیباگ سرویس‌ها ضروری است.

برای ورود به شل یک سرویس:

docker compose exec web sh

یا برای سرویس‌هایی که از bash استفاده می‌کنند:

docker compose exec web bash

این دستور برای بررسی وضعیت سرویس، اجرای تست‌ها یا مشاهده فایل‌ها بسیار کاربردی است.

اگر کد یا Dockerfile تغییر کرده باشد، باید سرویس‌ها دوباره ساخته شوند:

docker compose build

یا ساخت و اجرای هم‌زمان:

docker compose up --build

این دستور تضمین می‌کند که تغییرات جدید در ایمیج اعمال شده است.

Compose امکان اجرای چند نمونه از یک سرویس را فراهم می‌کند:

docker compose up --scale web=3

کاربرد عملی:

  • تست رفتار اپلیکیشن در حالت چند نمونه‌ای
  • شبیه‌سازی بار بیشتر روی سرویس‌ها

نکته: این قابلیت برای سرویس‌هایی که پورت ثابت دارند مناسب نیست، مگر اینکه پشت یک لودبالانسر قرار گیرند.

برای مشاهده وضعیت فعلی سرویس‌ها:

docker compose ps

این دستور نشان می‌دهد کدام سرویس‌ها در حال اجرا هستند و چه پورت‌هایی باز شده‌اند.

برای پاک‌سازی منابع بلااستفاده:

docker system prune

این دستور برای آزادسازی فضای دیسک مفید است، اما باید با دقت استفاده شود.

برای بازنشانی یک سرویس خاص:

docker compose restart web

این دستور تنها سرویس موردنظر را ری‌استارت می‌کند و سایر سرویس‌ها بدون تغییر باقی می‌مانند.

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

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

در اولین گام، باید از ذخیره‌کردن اطلاعات حساس داخل فایل Compose خودداری شود. بسیاری از توسعه‌دهندگان به‌صورت مستقیم رمز دیتابیس، کلیدهای API یا توکن‌ها را در بخش environment قرار می‌دهند. این کار باعث می‌شود اطلاعات حساس در کنترل نسخه ذخیره شود و در اختیار تمام اعضای تیم قرار گیرد. راه‌حل استاندارد استفاده از فایل env. است که در کنترل نسخه قرار نمی‌گیرد. برای نمونه:

services:
  db:
    image: postgres:15
    env_file:
      - .env

و فایل .env:

POSTGRES_USER=user
POSTGRES_PASSWORD=strong_password

این روش باعث می‌شود اطلاعات حساس از فایل Compose جدا شود و مدیریت آن‌ها ساده‌تر باشد.

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

services:
  web:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend

networks:
  frontend:
  backend:

در این ساختار، سرویس db تنها در شبکه backend قرار دارد و از دسترس سرویس‌های غیرضروری خارج است.

یکی از بهترین‌روش‌ها در پروژه‌های واقعی، استفاده از healthcheck برای سرویس‌های حیاتی است. بدون healthcheck، Compose تنها ترتیب اجرا را تضمین می‌کند، نه آماده‌بودن سرویس‌ها. این موضوع به‌ویژه برای دیتابیس‌ها اهمیت دارد. نمونه‌ای از healthcheck برای PostgreSQL:

services:
  db:
    image: postgres:15
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "user"]
      interval: 5s
      retries: 5

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

در پروژه‌هایی که نیاز به محدودکردن مصرف منابع دارند، استفاده از resource limits ضروری است. این کار از مصرف بیش‌ازحد CPU یا حافظه توسط یک سرویس جلوگیری می‌کند و پایداری محیط توسعه را افزایش می‌دهد. نمونه عملی:

services:
  web:
    deploy:
      resources:
        limits:
          cpus: "0.50"
          memory: "512M"

اگرچه بخش deploy در Compose بیشتر برای Swarm طراحی شده، اما بسیاری از ابزارها و محیط‌ها از این تنظیمات پشتیبانی می‌کنند.

در نهایت، استفاده از ولوم‌های امن و مدیریت‌شده اهمیت زیادی دارد. ولوم‌ها باید به‌صورت دقیق تعریف شوند و تنها سرویس‌هایی که نیاز دارند به آن‌ها دسترسی داشته باشند. برای مثال، اشتراک‌گذاری یک ولوم بین چند سرویس بدون دلیل منطقی می‌تواند باعث نشت داده یا تغییرات ناخواسته شود. ساختار صحیح:

services:
  db:
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

این ولوم تنها برای دیتابیس استفاده می‌شود و سرویس دیگری به آن دسترسی ندارد.

رعایت این نکات امنیتی و بهترین‌روش‌ها باعث می‌شود پروژه‌های مبتنی بر Docker Compose قابل‌اعتمادتر، پایدارتر و حرفه‌ای‌تر باشند. این اصول در پروژه‌های کوچک و بزرگ یکسان هستند و رعایت آن‌ها از همان مراحل اولیه توسعه، کیفیت کلی سیستم را به‌طور چشمگیری افزایش می‌دهد.

جمع‌بندی

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

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
در انتظار ثبت رای

/@arastoo
ارسطو عباسی
کارشناس تست نرم‌افزار و مستندات

...

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

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

ارسطو عباسی

کارشناس تست نرم‌افزار و مستندات

مقالات برگزیده

مقالات برگزیده را از این قسمت میتوانید ببینید

مشاهده همه مقالات