وبلاگ
ساخت اولین پروژه Docker Compose: از فایل `docker-compose.yml` تا اجرای سرویسها
فهرست مطالب
“تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”
"تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"
"با شرکت در این دوره جامع و کاربردی، به راحتی مهارتهای برنامهنویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر میسازد تا به سرعت الگوریتمهای پیچیده را درک کرده و اپلیکیشنهای هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفهای و امکان دانلود و تماشای آنلاین."
ویژگیهای کلیدی:
بدون نیاز به تجربه قبلی برنامهنویسی
زیرنویس فارسی با ترجمه حرفهای
۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان
0 تا 100 عطرسازی + (30 فرمولاسیون اختصاصی حامی صنعت)
دوره آموزش Flutter و برنامه نویسی Dart [پروژه محور]
دوره جامع آموزش برنامهنویسی پایتون + هک اخلاقی [با همکاری شاهک]
دوره جامع آموزش فرمولاسیون لوازم آرایشی
دوره جامع علم داده، یادگیری ماشین، یادگیری عمیق و NLP
دوره فوق فشرده مکالمه زبان انگلیسی (ویژه بزرگسالان)
شمع سازی و عودسازی با محوریت رایحه درمانی
صابون سازی (دستساز و صنعتی)
صفر تا صد طراحی دارو
متخصص طب سنتی و گیاهان دارویی
متخصص کنترل کیفی شرکت دارویی
ساخت اولین پروژه Docker Compose: از فایل docker-compose.yml تا اجرای سرویسها
در دنیای مدرن توسعه نرمافزار، معماریهای مبتنی بر میکروسرویسها و برنامههای توزیعشده به یک استاندارد طلایی تبدیل شدهاند. با این حال، مدیریت، استقرار و هماهنگسازی چندین سرویس مجزا که هر یک ممکن است در کانتینرهای جداگانه اجرا شوند، چالشهای خاص خود را دارد. اینجاست که Docker Compose به عنوان یک ابزار قدرتمند و حیاتی وارد عمل میشود.
Docker Compose به شما این امکان را میدهد که مجموعهای از سرویسهای کانتینری را با استفاده از یک فایل پیکربندی YAML واحد، تعریف، اجرا و مدیریت کنید. این فایل، که معمولاً docker-compose.yml نام دارد، به عنوان طرح اولیه (blueprint) برای کل اپلیکیشن چندسرویسی شما عمل میکند. هدف این مقاله، راهنمایی شما در ساخت اولین پروژه Docker Compose، از درک عمیق ساختار فایل docker-compose.yml گرفته تا اجرای موفقیتآمیز سرویسهای پیچیده و مدیریت دقیق آنها، برای توسعهدهندگان، مهندسان DevOps و مدیران سیستمهای باتجربه است.
ما به سراغ مباحثی خواهیم رفت که فراتر از اصول اولیه Docker هستند و به شما کمک میکنند تا از پتانسیل کامل Docker Compose برای ایجاد محیطهای توسعه سازگار، تستهای خودکار و حتی استقرارهای مقدماتی بهرهمند شوید. این راهنما نه تنها نحوه نوشتن یک فایل docker-compose.yml کارآمد را آموزش میدهد، بلکه به جزئیات پیکربندیهای پیشرفته، مدیریت وابستگیها، شبکهبندی پیچیده و استراتژیهای بهینهسازی نیز میپردازد. آماده باشید تا با ابزاری آشنا شوید که مدیریت اکوسیستم میکروسرویسی شما را متحول خواهد کرد.
مبانی docker-compose.yml: ساختار و مؤلفههای کلیدی
قلب هر پروژه Docker Compose، فایل docker-compose.yml (یا docker-compose.yaml) است. این فایل به فرمت YAML نوشته میشود و تمام اطلاعات لازم برای تعریف و اجرای سرویسهای شما را در بر میگیرد. درک ساختار این فایل برای استفاده مؤثر از Docker Compose ضروری است. در اینجا به مؤلفههای اصلی و نحوه سازماندهی آنها میپردازیم.
نسخه (version) فایل پیکربندی
اولین خط در فایل docker-compose.yml معمولاً تعیینکننده نسخه فرمت فایل پیکربندی است. این نسخه برای سازگاری با Docker Compose و قابلیتهای آن اهمیت دارد. آخرین نسخه پایدار و توصیهشده در حال حاضر 3.8 یا بالاتر است.
version: '3.8'
تعیین نسخه تضمین میکند که Compose فایل شما را به درستی تفسیر کرده و از تمامی قابلیتهای مربوط به آن نسخه پشتیبانی میکند. نادیده گرفتن این خط یا استفاده از نسخههای قدیمیتر میتواند منجر به خطاهای پیکربندی یا عدم پشتیبانی از ویژگیهای جدید شود.
بخش services: تعریف قلب پروژه
بخش services اصلیترین قسمت فایل docker-compose.yml است که در آن هر یک از سرویسهای برنامه شما تعریف میشوند. هر سرویس یک کانتینر مجزا (یا مجموعهای از کانتینرها در صورت اسکیلینگ) را نشان میدهد که با تنظیمات خاص خود اجرا میشود. در اینجا یک نمونه اولیه از نحوه تعریف یک سرویس آورده شده است:
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
environment:
- NGINX_PORT=80
app:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
depends_on:
- db
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydatabase
db:
image: postgres:13
environment:
- POSTGRES_DB=mydatabase
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- db_data:/var/lib/postgresql/data
در این مثال، سه سرویس web، app و db تعریف شدهاند. هر سرویس دارای یک نام منحصر به فرد است و زیر آن، پارامترهای پیکربندی آن سرویس قرار میگیرد.
پارامترهای کلیدی در تعریف سرویس:
image: نام ایمیج داکری که برای ساخت کانتینر استفاده میشود (مثلاًnginx:latest،postgres:13). اگر ایمیج در سیستم لوکال وجود نداشته باشد، Compose آن را از Docker Hub دانلود میکند.build: اگر میخواهید ایمیج سرویس را از یک Dockerfile بسازید، از این پارامتر استفاده کنید. میتوانید مسیر Dockerfile (به صورت نقطه.برای همان دایرکتوری، یا مسیر نسبی) یا یک شیء شاملcontextوdockerfileرا مشخص کنید.ports: برای مپ کردن پورتهای کانتینر به پورتهای میزبان (host). فرمت آن"HOST_PORT:CONTAINER_PORT"است.volumes: برای مپ کردن مسیرهای فایل سیستم میزبان به مسیرهای کانتینر، یا استفاده از Named Volumes برای ذخیرهسازی دائمی دادهها. فرمت آن"HOST_PATH:CONTAINER_PATH"یا"VOLUME_NAME:CONTAINER_PATH"است.environment: برای تعریف متغیرهای محیطی درون کانتینر. میتوانید آنها را به صورت لیستی ازKEY=VALUEیا یک نگاشت (map) تعریف کنید.depends_on: برای مشخص کردن وابستگیهای سرویس. این پارامتر تضمین میکند که سرویسهای وابسته قبل از سرویس فعلی شروع به کار کنند. با این حال، توجه داشته باشید کهdepends_onفقط ترتیب را تضمین میکند و نه سلامت سرویس (آماده بودن سرویس برای دریافت درخواست). برای بررسی سلامت، باید ازhealthcheckاستفاده کنید.networks: برای اتصال سرویس به یک یا چند شبکه تعریفشده.command: برای نادیده گرفتن دستور پیشفرض (CMD) در Dockerfile ایمیج و اجرای یک دستور دلخواه هنگام شروع کانتینر.entrypoint: برای نادیده گرفتن entrypoint پیشفرض ایمیج.restart: خطمشی ریاستارت کانتینر در صورت توقف یا خرابی (مثلاًalways،on-failure،no).
بخش volumes: مدیریت پایدار دادهها
دادههای درون کانتینرها ماهیت فرار (ephemeral) دارند؛ یعنی با حذف کانتینر، اطلاعات نیز از بین میروند. برای ذخیرهسازی دائمی دادهها و به اشتراکگذاری آنها بین کانتینرها، از volumes استفاده میشود. بخش volumes در ریشه فایل docker-compose.yml برای تعریف Named Volumes استفاده میشود.
volumes:
db_data:
driver: local
app_logs:
در اینجا، db_data و app_logs دو Named Volume هستند که توسط Compose ایجاد و مدیریت میشوند. سپس میتوانید در بخش services به این ولومها ارجاع دهید. استفاده از Named Volumes نسبت به Bind Mounts برای دادههای پایدار در محیطهای توسعه و تست ترجیح داده میشود، زیرا جداسازی بهتری را فراهم کرده و مدیریت آنها توسط Docker انجام میشود.
بخش networks: ارتباطات بین سرویسی
سرویسهای Docker Compose به صورت پیشفرض در یک شبکه Bridge مجزا قرار میگیرند که به آنها امکان میدهد با یکدیگر از طریق نام سرویسها ارتباط برقرار کنند. با این حال، در سناریوهای پیچیدهتر، ممکن است نیاز به تعریف شبکههای سفارشی، شبکههای خارجی یا پیکربندیهای پیشرفتهتری داشته باشید.
networks:
backend_network:
driver: bridge
frontend_network:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
external_db_network:
external: true
name: my_existing_network
در این مثال:
backend_networkوfrontend_networkشبکههای Bridge سفارشی هستند که Compose آنها را ایجاد میکند. برایfrontend_networkیک محدوده IP سفارشی نیز تعیین شده است.external_db_networkبه یک شبکه Bridge موجود در Docker اشاره دارد که از قبل ایجاد شده است (مثلاًdocker network create my_existing_network). این برای اتصال پروژه Compose به سرویسهایی که خارج از این فایل Compose مدیریت میشوند، مفید است.
سپس، هر سرویس میتواند به یک یا چند شبکه متصل شود:
services:
web:
image: nginx
networks:
- frontend_network
app:
image: my_app
networks:
- frontend_network
- backend_network
db:
image: postgres
networks:
- backend_network
با این پیکربندی، سرویس web و app در frontend_network قرار دارند و میتوانند با هم ارتباط برقرار کنند. سرویس app و db در backend_network هستند و میتوانند با هم صحبت کنند. اما web و db نمیتوانند مستقیماً با هم ارتباط برقرار کنند مگر اینکه از طریق app یا از طریق یک شبکه مشترک دیگر.
درک عمیق این سه بخش اصلی (services، volumes، networks) اساسیترین قدم برای ساخت و مدیریت هر پروژه Docker Compose است. با تسلط بر این ساختار، میتوانید به سراغ پیکربندیهای پیشرفتهتر بروید و پتانسیل کامل این ابزار را کشف کنید.
پیکربندی پیشرفته سرویسها: Build، Image، Environment و Port Mapping
در بخش قبلی با مبانی docker-compose.yml آشنا شدیم. اکنون زمان آن است که به جزئیات بیشتری در مورد پیکربندی سرویسها بپردازیم. هر سرویس در Docker Compose مجموعهای از گزینهها را پشتیبانی میکند که به شما امکان میدهد رفتار کانتینر را با دقت بالایی کنترل کنید.
تفاوت image و build: انتخاب صحیح استراتژی ایمیج
یکی از تصمیمات مهم در تعریف یک سرویس، انتخاب بین استفاده از یک ایمیج موجود (image) یا ساخت ایمیج از طریق Dockerfile (build) است.
استفاده از image:
این رویکرد زمانی مناسب است که شما قصد دارید از یک ایمیج آماده و منتشر شده در Docker Hub یا یک رجیستری خصوصی استفاده کنید. این روش سادهترین راه برای راهاندازی سرویسها است و زمان ساخت ایمیج را حذف میکند.
services:
database:
image: postgres:13.4-alpine
environment:
POSTGRES_DB: myapp_db
POSTGRES_USER: user
POSTGRES_PASSWORD: secretpassword
در اینجا، Compose ایمیج postgres:13.4-alpine را دانلود کرده و کانتینر را از آن اجرا میکند.
استفاده از build:
اگر پروژه شما شامل کد برنامهای است که نیاز به کامپایل یا نصب وابستگیها دارد و شما میخواهید ایمیج سفارشی خود را بسازید، از build استفاده میکنید. این گزینه به Compose میگوید که به دنبال یک Dockerfile بگردد و ایمیج را از آن بسازد.
services:
app:
build: . # به Compose می گوید Dockerfile را در دایرکتوری جاری پیدا کند
# یا می تواند یک مسیر نسبی باشد، مثلاً ./backend/Dockerfile
ports:
- "8000:8000"
environment:
NODE_ENV: development
برای کنترل دقیقتر فرآیند ساخت، میتوانید یک شیء پیکربندی برای build ارائه دهید:
services:
app:
build:
context: ./backend # مسیر دایرکتوری که Dockerfile و فایلهای مرتبط در آن قرار دارند
dockerfile: Dockerfile.dev # نام فایل Dockerfile (اختیاری، پیشفرض Dockerfile)
args: # آرگومانهایی که در زمان ساخت به Dockerfile ارسال میشوند (ARG)
NODE_VERSION: 16
DEBUG_MODE: "true"
target: development-stage # استفاده از multi-stage build targets
استفاده از context به شما امکان میدهد تعیین کنید که Docker build engine از کدام دایرکتوری برای دسترسی به فایلها استفاده کند. dockerfile برای تعیین نام فایل Dockerfile سفارشی است. args برای ارسال متغیرها در زمان ساخت (Build-time variables) و target برای بهرهگیری از قابلیت Multi-stage builds در Dockerfileها استفاده میشود که به شما اجازه میدهد ایمیجهای بهینهتر و کوچکتری تولید کنید.
مدیریت متغیرهای محیطی (environment)
متغیرهای محیطی یکی از رایجترین راهها برای پیکربندی برنامهها در کانتینرها هستند. Docker Compose چندین روش برای تزریق متغیرهای محیطی ارائه میدهد:
- تعریف مستقیم در فایل
docker-compose.yml: - استفاده از متغیرهای محیطی میزبان:
- فایل
.env:
services:
app:
environment:
- DB_HOST=database
- DB_PORT=5432
- API_KEY=some_secret_key
این روش برای متغیرهای غیرحساس و ثابت مناسب است.
میتوانید به متغیرهای محیطی تعریفشده در سیستم عامل میزبان اشاره کنید:
services:
app:
environment:
- API_KEY=${MY_API_KEY} # MY_API_KEY باید در محیط میزبان تعریف شده باشد
- DEBUG_MODE=${DEBUG:-false} # مقدار پیشفرض "false" اگر DEBUG تعریف نشده باشد
این روش برای مواردی که نمیخواهید مقادیر حساس را مستقیماً در فایل docker-compose.yml ذخیره کنید (مثلاً API Keyها یا رمز عبور) بسیار مفید است.
Compose به صورت خودکار به دنبال یک فایل با نام .env در همان دایرکتوری فایل docker-compose.yml میگردد و متغیرهای تعریفشده در آن را بارگذاری میکند. این بهترین روش برای مدیریت متغیرهای محیطی در توسعه محلی است.
مثال فایل .env:
# .env
MY_API_KEY=your_development_api_key
DEBUG=true
DB_CONNECTION_STRING=postgres://dev_user:dev_pass@localhost:5432/dev_db
سپس در docker-compose.yml میتوانید به آنها اشاره کنید:
services:
app:
environment:
- API_KEY=${MY_API_KEY}
- DEBUG_MODE=${DEBUG}
- DATABASE_URL=${DB_CONNECTION_STRING}
این روش، جداسازی پیکربندی حساس از کد منبع را بهبود میبخشد و امکان مدیریت آسان متغیرها برای محیطهای مختلف (توسعه، تست، پروداکشن) را فراهم میکند.
مپ کردن پورتها (ports)
گزینه ports برای نمایش پورتهای سرویس کانتینر به خارج از محیط داکر و در دسترس قرار دادن آنها بر روی میزبان استفاده میشود. فرمت استاندارد آن "HOST_PORT:CONTAINER_PORT" است.
services:
web:
image: nginx
ports:
- "80:80" # پورت 80 میزبان به پورت 80 کانتینر
- "443:443" # پورت 443 میزبان به پورت 443 کانتینر
api:
image: myapi
ports:
- "8080:5000" # پورت 8080 میزبان به پورت 5000 کانتینر
اگر تنها پورت کانتینر را مشخص کنید (مثلاً "80")، Docker یک پورت رندوم و آزاد بر روی میزبان برای آن انتخاب میکند. این برای جلوگیری از تداخل پورتها در محیط توسعه مفید است، اما برای دسترسیهای عمومی توصیه نمیشود.
services:
test_service:
image: some_app
ports:
- "80" # یک پورت رندوم بر روی میزبان به پورت 80 کانتینر مپ می شود
پیکربندی منابع (resources): cpu_shares، mem_limit
برای اطمینان از عملکرد پایدار و جلوگیری از مصرف بیش از حد منابع توسط یک کانتینر، میتوانید محدودیتهایی برای CPU و حافظه اعمال کنید. این تنظیمات در بخش deploy و زیر resources قرار میگیرند (که بیشتر برای استفاده در حالت Swarm Mode است، اما در Docker Compose مستقل نیز قابل استفاده است).
services:
api:
image: myapi
deploy:
resources:
limits:
cpus: '0.5' # حداکثر 0.5 هسته CPU
memory: 512M # حداکثر 512 مگابایت حافظه
reservations:
cpus: '0.2' # حداقل 0.2 هسته CPU (تضمین شده)
memory: 256M # حداقل 256 مگابایت حافظه (تضمین شده)
limits حداکثر منابعی را که کانتینر میتواند مصرف کند، تعیین میکند، در حالی که reservations حداقل منابع تضمینشده را مشخص میکند. این برای سرویسهای حیاتی که به حداقل منابع خاصی نیاز دارند، مفید است.
مدیریت دسترسی (user، group_add) و امتیازات
برای افزایش امنیت، توصیه میشود کانتینرها را با کاربر غیر root اجرا کنید. میتوانید این کار را با user انجام دهید:
services:
app:
image: myapp
user: "1000:1000" # uid:gid (مثلاً کاربر غیر root و گروه در سیستم عامل میزبان)
همچنین، میتوانید گروههای اضافی را به کانتینر اضافه کنید تا دسترسی به فایلها و دایرکتوریهای خاصی را فراهم کنید:
services:
app:
image: myapp
group_add:
- "100" # اضافه کردن کانتینر به گروهی با GID 100
این پیکربندیها به شما کمک میکنند تا سرویسهای Docker Compose خود را با دقت و امنیت بیشتری مدیریت کنید و آنها را برای سناریوهای مختلف توسعه و استقرار آماده سازید.
مدیریت وابستگیها و سلامت سرویسها: depends_on و healthcheck
در یک معماری میکروسرویس، سرویسها به ندرت به صورت ایزوله عمل میکنند. اغلب، یک سرویس برای عملکرد صحیح به سرویسهای دیگر (مانند پایگاه داده، کش یا APIهای دیگر) وابسته است. Docker Compose ابزارهایی برای مدیریت این وابستگیها و اطمینان از سلامت سرویسها قبل از شروع به کار سایر کامپوننتها ارائه میدهد.
depends_on: ترتیب شروع سرویسها
پارامتر depends_on به Compose میگوید که یک سرویس باید قبل از سرویس دیگری شروع شود. این یک وابستگی در سطح شروع کانتینر ایجاد میکند، به این معنی که Compose تضمین میکند کانتینرهای وابسته قبل از کانتینر فعلی شروع به کار کنند.
services:
web:
image: nginx
depends_on:
- app # web به app وابسته است، پس app اول شروع می شود
app:
build: .
depends_on:
- db # app به db وابسته است، پس db اول شروع می شود
db:
image: postgres
در این مثال، db اول شروع میشود، سپس app و در نهایت web. اما یک نکته بسیار مهم وجود دارد: depends_on فقط تضمین میکند که کانتینر شروع شده باشد، نه اینکه سرویس داخل آن کانتینر آماده دریافت درخواستها باشد. به عنوان مثال، db ممکن است شروع شود، اما پایگاه داده Postgres هنوز در حال مقداردهی اولیه باشد و برای اتصال آماده نباشد.
برای حل این مشکل، نیاز به مکانیزمی برای بررسی “آمادگی” (readiness) سرویسها داریم.
healthcheck: تضمین سلامت و آمادگی سرویس
healthcheck یک قابلیت حیاتی است که به Docker اجازه میدهد تا وضعیت سلامت یک کانتینر را به صورت دورهای بررسی کند. Compose میتواند از اطلاعات healthcheck برای تعیین اینکه آیا یک سرویس آماده و عملیاتی است، استفاده کند. این به ما امکان میدهد وابستگیهای “آمادگی” را به جای وابستگیهای “شروع” ایجاد کنیم.
یک healthcheck معمولاً شامل یک دستور (command) است که در داخل کانتینر اجرا میشود و وضعیت خروج (exit code) آن نشاندهنده سلامت است (0 برای سالم، 1 برای ناسالم).
services:
db:
image: postgres:13
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydatabase"] # دستور بررسی سلامت
interval: 5s # هر 5 ثانیه بررسی کن
timeout: 5s # اگر تست در 5 ثانیه جواب نداد، آن را ناموفق تلقی کن
retries: 5 # 5 بار تلاش کن قبل از اینکه سرویس را ناسالم اعلام کنی
start_period: 30s # 30 ثانیه بعد از شروع برای اولین تست صبر کن
در این مثال:
test: دستورpg_isreadyرا برای بررسی اتصال به پایگاه داده اجرا میکند.interval: هر چند وقت یک بار تست باید اجرا شود.timeout: حداکثر زمانی که تست میتواند طول بکشد.retries: تعداد دفعاتی که تست میتواند ناموفق باشد قبل از اینکه کانتینر ناسالم اعلام شود.start_period: یک دوره زمانی اولیه که در طی آن تستها میتوانند ناموفق باشند بدون اینکه کانتینر بلافاصله ناسالم اعلام شود. این برای سرویسهایی که نیاز به زمان برای مقداردهی اولیه دارند، مفید است.
ترکیب depends_on با condition: service_healthy
برای حل مشکل عدم آمادگی سرویسها در depends_on، میتوانید از یک فرمت پیشرفتهتر برای depends_on در نسخه 3 از Compose استفاده کنید که با healthcheck ترکیب میشود:
services:
web:
image: nginx
ports:
- "80:80"
depends_on:
app:
condition: service_healthy # web فقط زمانی شروع می شود که app سالم باشد
app:
build: .
ports:
- "5000:5000"
environment:
DATABASE_URL: postgresql://user:password@db:5432/mydatabase
depends_on:
db:
condition: service_healthy # app فقط زمانی شروع می شود که db سالم باشد
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"] # فرض کنید اپلیکیشن یک endpoint سلامت دارد
interval: 10s
timeout: 5s
retries: 3
start_period: 15s
db:
image: postgres:13
environment:
- POSTGRES_DB=mydatabase
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydatabase"]
interval: 5s
timeout: 5s
retries: 5
start_period: 30s
در این سناریو، Compose اطمینان حاصل میکند که:
- سرویس
dbشروع شده وhealthcheckآن وضعیت “healthy” را برگردانده باشد. - سرویس
app(که وابسته بهdbاست) شروع میشود و پس از آن،healthcheckخودappنیز وضعیت “healthy” را برگرداند. - در نهایت، سرویس
web(که وابسته بهappاست) شروع میشود.
این رویکرد به شما کنترل بسیار دقیقی بر ترتیب شروع و آمادگی سرویسها میدهد و از خطاهای زمان راهاندازی که ناشی از عدم آمادگی وابستگیها هستند، جلوگیری میکند. پیادهسازی healthcheck برای هر سرویس حیاتی یک بهترین عمل است.
شبکهبندی و ذخیرهسازی دادهها: از bridge تا named volumes
مدیریت ارتباطات بین سرویسها و پایداری دادهها از ستونهای اصلی هر برنامه مبتنی بر کانتینر است. Docker Compose ابزارهای قدرتمندی برای هر دو حوزه فراهم میکند که از تنظیمات پیشفرض ساده تا پیکربندیهای پیچیده و سفارشی را شامل میشود.
مفاهیم شبکهبندی در Docker Compose
به صورت پیشفرض، زمانی که شما یک پروژه Docker Compose را بالا میآورید، Compose یک شبکه Bridge اختصاصی برای آن پروژه ایجاد میکند. تمام سرویسهای تعریفشده در فایل docker-compose.yml به این شبکه متصل میشوند و میتوانند با استفاده از نام سرویسهایشان با یکدیگر ارتباط برقرار کنند. به عنوان مثال، اگر سرویسی به نام db دارید، سرویس app میتواند با استفاده از db به آن دسترسی پیدا کند.
شبکههای پیشفرض و سفارشی
شبکه پیشفرض (Default Network):
برای یک پروژه ساده، نیازی به تعریف صریح شبکه نیست. Compose به صورت خودکار یک شبکه با نام <projectname>_default ایجاد میکند.
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx
app:
image: myapp
در این حالت، web و app هر دو در شبکه <projectname>_default قرار دارند و میتوانند با یکدیگر ارتباط برقرار کنند.
تعریف شبکههای سفارشی (Custom Networks):
در سناریوهای پیچیدهتر، ممکن است بخواهید چندین شبکه ایجاد کرده و سرویسها را به طور انتخابی به آنها متصل کنید تا جداسازی شبکه (network segmentation) را بهبود بخشید یا مسیرهای ارتباطی خاصی را تعریف کنید. این کار به افزایش امنیت و کنترل جریان دادهها کمک میکند.
version: '3.8'
services:
web:
image: nginx
ports:
- "80:80"
networks:
- frontend # web تنها به frontend متصل است
app:
image: myapp
networks:
- frontend # app هم به frontend متصل است
- backend # و هم به backend
db:
image: postgres
networks:
- backend # db تنها به backend متصل است
networks:
frontend:
driver: bridge # یک شبکه bridge به نام frontend ایجاد می کند
backend:
driver: bridge # یک شبکه bridge به نام backend ایجاد می کند
در این پیکربندی:
webوappمیتوانند با یکدیگر ارتباط برقرار کنند (از طریقfrontend).appوdbمیتوانند با یکدیگر ارتباط برقرار کنند (از طریقbackend).- اما
webنمیتواند مستقیماً باdbارتباط برقرار کند، زیرا آنها هیچ شبکه مشترکی ندارند. این یک الگوی رایج برای جدا کردن لایههای مختلف یک اپلیکیشن است (مثلاً لایه UI از لایه دیتابیس).
شبکههای خارجی (External Networks)
گاهی اوقات، شما نیاز دارید که پروژه Docker Compose خود را به یک شبکه Docker موجود که خارج از فایل docker-compose.yml مدیریت میشود، متصل کنید. این برای ادغام با سایر سرویسهای Docker یا حتی برای محیطهای پروداکشن که شبکهبندی به صورت مرکزی مدیریت میشود، مفید است.
version: '3.8'
services:
app:
image: myapp
networks:
- existing_shared_network # به شبکه خارجی متصل می شود
networks:
existing_shared_network:
external: true # به Compose می گوید که این شبکه از قبل وجود دارد
name: global_docker_network # نام شبکه خارجی در Docker
قبل از اجرای این Compose، باید شبکه global_docker_network را به صورت دستی (docker network create global_docker_network) ایجاد کرده باشید.
مفاهیم ذخیرهسازی دادهها در Docker Compose
همانطور که قبلاً اشاره شد، دادههای داخل کانتینرها پایدار نیستند. برای حفظ دادهها بین دفعات راهاندازی کانتینرها یا به اشتراکگذاری دادهها، از Voluems استفاده میشود.
Bind Mounts:
Bind Mounts به شما امکان میدهند یک فایل یا دایرکتوری از سیستم فایل میزبان را مستقیماً به یک مسیر در کانتینر مپ کنید. این روش بیشتر برای توسعه محلی مفید است، جایی که میخواهید تغییرات کد خود را بلافاصله در کانتینر منعکس کنید.
services:
app:
image: myapp
volumes:
- ./src:/app/src # مپ کردن دایرکتوری src پروژه به /app/src در کانتینر
- ./config.yml:/app/config.yml:ro # مپ کردن فایل با دسترسی فقط خواندنی
نکات:
- مسیر میزبان (
./src) میتواند نسبی به دایرکتوری فایلdocker-compose.ymlباشد. :roبه معنی Read-Only است که از تغییر فایلها در کانتینر جلوگیری میکند.
Named Volumes:
Named Volumes توسط Docker مدیریت میشوند و در یک قسمت خاص از سیستم فایل میزبان (معمولاً /var/lib/docker/volumes/) ذخیره میشوند. این روش بهترین انتخاب برای دادههای پایدار (مانند پایگاه دادهها) در محیطهای توسعه و تست و حتی در برخی سناریوهای پروداکشن است.
version: '3.8'
services:
db:
image: postgres:13
volumes:
- db_data:/var/lib/postgresql/data # دادههای Postgres در ولوم db_data ذخیره می شوند
app_data:
image: myapp_worker
volumes:
- app_logs:/var/log/myapp # لاگهای اپلیکیشن در ولوم app_logs ذخیره می شوند
volumes:
db_data: # تعریف Named Volume به نام db_data
driver: local
app_logs: # تعریف Named Volume به نام app_logs
driver: local
مزایای Named Volumes:
- مدیریت آسان: Docker مسئول ایجاد و مدیریت ولوم است.
- قابلیت انتقال: میتوانند به راحتی بین کانتینرها به اشتراک گذاشته شوند.
- عملکرد: در برخی موارد، ممکن است عملکرد بهتری نسبت به Bind Mounts داشته باشند.
- پایداری: دادهها حتی پس از حذف کانتینرها نیز باقی میمانند (تا زمانی که ولوم حذف نشود).
Anonymous Volumes:
این ولومها شبیه Named Volumes هستند اما نامی ندارند و توسط Docker با یک شناسه تصادفی ایجاد میشوند. معمولاً برای دادههای موقت که نیازی به نگهداری طولانیمدت ندارند، استفاده میشوند. با این حال، استفاده از Named Volumes برای بیشتر سناریوها توصیه میشود.
services:
temp_cache:
image: redis
volumes:
- /data # یک ولوم ناشناس به /data در کانتینر متصل می شود
با درک و استفاده صحیح از مفاهیم شبکهبندی و ذخیرهسازی دادهها، میتوانید پروژههای Docker Compose پایدار، امن و با عملکرد بالا ایجاد کنید که به خوبی نیازهای برنامههای مدرن و توزیعشده را برآورده سازند.
اسکیلینگ و مدیریت منابع: بهینهسازی عملکرد و پایداری
یکی از مزایای کلیدی کانتینرسازی و ابزارهایی مانند Docker Compose، توانایی اسکیل کردن (افزایش تعداد نمونهها) سرویسها و مدیریت مؤثر منابع سختافزاری است. این قابلیت به شما امکان میدهد تا برنامههایی را بسازید که میتوانند با افزایش بار کاری سازگار شوند و در عین حال، مصرف منابع را تحت کنترل نگه دارند.
اسکیلینگ سرویسها (Scaling Services)
Docker Compose به شما اجازه میدهد تا به راحتی تعداد نمونههای (replica) یک سرویس را افزایش دهید. این کار به توزیع بار کاری بین چندین کانتینر و افزایش دسترسپذیری کمک میکند. اسکیلینگ سرویسها میتواند به دو روش انجام شود:
اسکیلینگ در زمان اجرا (Runtime Scaling):
سادهترین راه برای اسکیل کردن یک سرویس، استفاده از دستور docker-compose up --scale است. به عنوان مثال، اگر میخواهید سرویس web خود را به 3 نمونه اسکیل کنید:
docker-compose up -d --scale web=3
این دستور 3 کانتینر از سرویس web را راهاندازی میکند. Compose به صورت خودکار پورتهای رندوم را به کانتینرها اختصاص میدهد مگر اینکه شما پورتهای مشخصی را مپ کرده باشید. در صورت استفاده از Load Balancer یا Reverse Proxy (مانند Nginx یا Traefik) در جلوی سرویسها، این رویکرد بسیار کارآمد است.
اسکیلینگ از طریق فایل پیکربندی (Configuration Scaling):
اگرچه --scale برای تنظیم موقت تعداد نمونهها مفید است، اما برای تعریف دائمی تعداد نمونههای مطلوب (مثلاً برای محیطهای تست یا پروداکشن) بهتر است از گزینه replicas در بخش deploy استفاده کنید. توجه داشته باشید که گزینه replicas عمدتاً برای استفاده با Docker Swarm mode طراحی شده است، اما Docker Compose نیز میتواند از آن برای راهاندازی چندین کانتینر استفاده کند، هرچند که Load Balancing پیشرفتهای را مانند Swarm ارائه نمیدهد.
version: '3.8'
services:
web:
image: my_nginx_proxy
ports:
- "80:80"
deploy:
replicas: 2 # دو نمونه از سرویس web را اجرا کن
app:
build: .
deploy:
replicas: 3 # سه نمونه از سرویس app را اجرا کن
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydatabase
در این پیکربندی، هنگام اجرای docker-compose up -d، Compose به ترتیب 2 نمونه از web و 3 نمونه از app را راهاندازی میکند. برای مدیریت ترافیک ورودی به این نمونهها، معمولاً به یک لود بالانسر خارجی (مانند Nginx که خود در Compose تعریف شده) نیاز خواهید داشت.
مدیریت و محدودیت منابع (Resource Management and Limits)
برای اطمینان از عملکرد پایدار و جلوگیری از “noisy neighbor” effect (زمانی که یک سرویس بیش از حد منابع مصرف میکند و بر سرویسهای دیگر تأثیر میگذارد)، میتوانید محدودیتهایی را برای CPU و حافظه اعمال کنید. این محدودیتها در بخش deploy.resources تعریف میشوند:
محدودیتهای CPU:
cpus: حداکثر مقدار CPU که کانتینر میتواند مصرف کند. این مقدار میتواند یک عدد اعشاری باشد که نشاندهنده تعداد هستهها یا بخشی از یک هسته است (مثلاً'0.5'یعنی نیم هسته).cpu_shares: سهم نسبی CPU که کانتینر دریافت میکند. اگر چندین کانتینر در حال رقابت برای CPU باشند، کانتینری باcpu_sharesبالاتر، سهم بیشتری از CPU موجود را دریافت میکند. این یک مقدار نسبی است نه مطلق.cpu_percent: درصد استفاده از CPU. (کمتر استفاده میشود و معمولاًcpusترجیح داده میشود.)cpu_periodوcpu_quota: برای کنترل دقیقتر زمانبندی CPU.cpu_periodمدت زمان یک چرخه زمانبندی را تعریف میکند (پیشفرض 100000 میکروثانیه) وcpu_quotaحداکثر زمانی است که کانتینر میتواند در یک دوره از CPU استفاده کند (مثلاًcpu_quota: 50000باcpu_period: 100000به معنی 50% استفاده از CPU است).
services:
cpu_intensive_app:
image: my_cruncher
deploy:
resources:
limits:
cpus: '1.0' # حداکثر 1 هسته CPU
reservations:
cpus: '0.5' # تضمین حداقل 0.5 هسته CPU
cpu_shares: 512 # در حالت رقابت، دو برابر سهم پیشفرض (1024)
limits.cpus بهترین راه برای اعمال محدودیت سخت CPU است. reservations.cpus برای تضمین حداقل منابع در محیطهایی که تخصیص منابع بیش از حد (overcommitment) انجام میشود، مفید است.
محدودیتهای حافظه:
memory(یاmem_limit): حداکثر مقدار حافظه RAM که کانتینر میتواند مصرف کند (مثلاً512M،2G).memory_reservation(یاmem_reservation): حداقل مقدار حافظه RAM که برای کانتینر رزرو میشود. این مقدار حافظه همیشه برای کانتینر در دسترس خواهد بود.memory_swap: حداکثر مقدار حافظه RAM + Swap که کانتینر میتواند استفاده کند.
services:
memory_hog_app:
image: my_data_processor
deploy:
resources:
limits:
memory: 2G # حداکثر 2 گیگابایت حافظه
reservations:
memory: 1G # تضمین حداقل 1 گیگابایت حافظه
ترکیب اسکیلینگ با مدیریت منابع، به شما این امکان را میدهد که برنامههایی را با عملکرد بهینه و قابلیت اطمینان بالا طراحی و اجرا کنید. این موضوع در محیطهای پروداکشن، جایی که منابع محدود و پایداری سرویسها حیاتی است، اهمیت دوچندانی پیدا میکند.
توسعه و دیباگینگ با Docker Compose: Workflowهای پیشرفته
Docker Compose نه تنها برای استقرار بلکه به طور ویژه برای بهینهسازی فرآیند توسعه و دیباگینگ برنامههای چندسرویسی طراحی شده است. استفاده مؤثر از آن میتواند زمان توسعه را به طور قابل توجهی کاهش داده و تجربه توسعهدهنده را بهبود بخشد.
محیط توسعه سازگار و ایزوله
یکی از بزرگترین مزایای Docker Compose، ایجاد یک محیط توسعه کاملاً سازگار و ایزوله است. این بدان معناست که:
- حذف “It works on my machine” problem: تمام اعضای تیم از یک محیط کاملاً یکسان استفاده میکنند، که مشکلات مربوط به تفاوت نسخههای dependency، سیستم عامل یا تنظیمات محلی را از بین میبرد.
- راهاندازی سریع پروژه: توسعهدهندگان جدید میتوانند تنها با یک دستور (
docker-compose up) کل stack برنامه را راهاندازی کنند، بدون نیاز به نصب دستی پایگاه دادهها، سرورهای وب و سایر dependencyها. - انعطافپذیری: میتوانید چندین پروژه را به صورت موازی با dependencyهای متفاوت و بدون تداخل روی یک ماشین توسعه دهید.
استفاده از Bind Mounts برای بازخورد لحظهای
در حین توسعه، معمولاً میخواهید تغییرات کد خود را بلافاصله مشاهده کنید، بدون نیاز به بازسازی ایمیج یا راهاندازی مجدد کانتینر. Bind Mounts بهترین راه برای دستیابی به این هدف هستند.
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev # استفاده از یک Dockerfile مخصوص توسعه
volumes:
- ./src:/app/src # مپ کردن کد منبع لوکال به داخل کانتینر
- /app/node_modules # جلوگیری از مپ شدن node_modules لوکال روی کانتینر (برای Node.js)
ports:
- "3000:3000"
environment:
NODE_ENV: development
command: npm run dev # دستور اجرای اپلیکیشن در حالت توسعه
در این مثال:
- فایلهای کد منبع در
./srcمستقیماً به/app/srcدر کانتینر مپ میشوند. - با استفاده از
/app/node_modules(که یک Named Volume ناشناس ایجاد میکند)، مطمئن میشویم کهnode_modulesداخل کانتینر استفاده میشود، نهnode_modulesمحلی روی میزبان که ممکن است با معماری کانتینر ناسازگار باشد. - دستور
npm run devمعمولاً شامل یک watch mode است که با تغییر فایلها، سرور را بهطور خودکار ریاستارت یا hot-reload میکند.
فایلهای docker-compose.yml چندگانه (Multiple Compose Files)
برای مدیریت پیکربندیهای مختلف برای محیطهای توسعه، تست و پروداکشن، Docker Compose از قابلیت استفاده از چندین فایل Compose پشتیبانی میکند. این به شما امکان میدهد تا پیکربندیهای پایه را در یک فایل (مثلاً docker-compose.yml) قرار داده و سپس آنها را با فایلهای مخصوص محیط (مثلاً docker-compose.dev.yml، docker-compose.prod.yml) بسط دهید.
مثال docker-compose.yml (پیکربندی پایه):
# docker-compose.yml (پیکربندی پایه)
version: '3.8'
services:
app:
build: .
ports:
- "80:80"
environment:
- API_KEY=${API_KEY}
db:
image: postgres:13
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
مثال docker-compose.dev.yml (پیکربندی توسعه، اضافه کردن Bind Mounts و تنظیمات دیباگ):
# docker-compose.dev.yml (پیکربندی مخصوص توسعه)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev # استفاده از Dockerfile مخصوص توسعه
volumes:
- ./src:/app/src # Bind Mount برای کد منبع
- /app/node_modules # Named Volume برای پکیجها
environment:
NODE_ENV: development
DEBUG_PORT: "9229" # پورت دیباگ Node.js
command: npm run dev_debug # اجرای برنامه با دیباگر
ports:
- "9229:9229" # مپ کردن پورت دیباگ
برای راهاندازی محیط توسعه، از دستور زیر استفاده میکنید:
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
Compose فایلها را به ترتیب ادغام میکند. تنظیمات در فایلهای بعدی، تنظیمات قبلی را override میکنند. این یک روش قدرتمند برای حفظ DRY (Don’t Repeat Yourself) و مدیریت آسان تفاوتهای محیطی است.
دیباگینگ با Docker Compose
دیباگینگ برنامههای کانتینری نیاز به مپ کردن پورتهای دیباگ و استفاده از ابزارهای دیباگ مناسب دارد:
- پیکربندی پورت دیباگ: در
docker-compose.dev.yml، پورت دیباگ سرویس خود را مپ کنید (مثلاً"9229:9229"برای Node.js). - اجرای سرویس با دیباگر: مطمئن شوید که
commandیاentrypointسرویس شما، برنامه را با پرچمهای دیباگ مناسب اجرا میکند (مثلاًnode --inspect-brk=0.0.0.0:9229 index.jsبرای Node.js). - اتصال دیباگر: از IDE خود (مانند VS Code) یا ابزارهای دیباگ دیگر برای اتصال به کانتینر از طریق پورت مپشده (مثلاً
localhost:9229) استفاده کنید.
استفاده از docker-compose run برای وظایف یکباره
دستور docker-compose run برای اجرای یک دستور یکباره در یک کانتینر جدید بر اساس پیکربندی یک سرویس استفاده میشود. این برای اجرای migrationهای پایگاه داده، دستورات مدیریت (management commands) یا اجرای تستها عالی است.
docker-compose run app python manage.py migrate # اجرای migration در کانتینر app
docker-compose run --rm app python manage.py test # اجرای تست ها و حذف کانتینر پس از اتمام
با استفاده از --rm، کانتینر پس از اتمام کار به صورت خودکار حذف میشود. این ابزارها، همراه با قابلیتهای اصلی Compose، تجربه توسعه شما را در محیطهای کانتینری به شدت بهبود میبخشند و به شما امکان میدهند تا با پیچیدگیهای معماری میکروسرویس به طور مؤثرتری کنار بیایید.
استقرار و نکات امنیتی: انتقال از توسعه به پروداکشن (نکات مقدماتی)
در حالی که Docker Compose یک ابزار فوقالعاده برای توسعه و تست محلی است، استفاده از آن به طور مستقیم در محیطهای پروداکشن با چالشهایی همراه است. با این حال، میتوان از آن به عنوان یک ابزار استقرار ساده برای برنامههای کوچک یا برای مراحل اولیه استقرار استفاده کرد، با رعایت برخی ملاحظات امنیتی و عملکردی.
ملاحظات امنیتی
- عدم افشای اطلاعات حساس (Secrets Management):
هرگز اطلاعات حساس مانند رمز عبور، API Keyها یا توکنها را مستقیماً در فایل
docker-compose.ymlیا.envکه در مخزن کد نگهداری میشود، قرار ندهید. به جای آن، از روشهای امنتری استفاده کنید:- متغیرهای محیطی سیستم عامل: در محیط پروداکشن، متغیرها را مستقیماً در محیط سیستم عامل میزبان تعریف کنید (
export MY_SECRET=value) و در Compose به آنها اشاره کنید (${MY_SECRET}). - Docker Secrets (در Swarm Mode): برای استقرارهای پیچیدهتر و در Swarm Mode، Docker Secrets یک راهکار داخلی و امن برای مدیریت اطلاعات حساس است.
- Vaults (مانند HashiCorp Vault): برای سناریوهای enterprise، استفاده از Vaultهای متمرکز برای مدیریت و توزیع Secretها توصیه میشود.
env_fileبا فایلهای محدود شده: میتوانید یک فایل.env.prodایجاد کرده و آن را در.gitignoreقرار دهید و سپس ازenv_file: .env.prodدر Compose استفاده کنید، اما باید مطمئن شوید که این فایل هرگز به مخزن کد push نمیشود.
services: app: image: myapp:latest environment: - DB_PASSWORD=${DB_PASSWORD} # متغیر محیطی از سیستم عامل میزبان secrets: # برای Docker Swarm Mode - my_app_api_key secrets: my_app_api_key: external: true - متغیرهای محیطی سیستم عامل: در محیط پروداکشن، متغیرها را مستقیماً در محیط سیستم عامل میزبان تعریف کنید (
- ایمیجهای داکر امن:
- استفاده از ایمیجهای پایه کوچک و امن: از ایمیجهای پایه مانند Alpine یا Slim برای کاهش حجم و سطح حمله (attack surface) استفاده کنید (مثلاً
python:3.9-alpine). - Multi-stage Builds: از Multi-stage builds در Dockerfileهای خود استفاده کنید تا ایمیج نهایی فقط شامل کد و وابستگیهای ضروری باشد و ابزارهای Build-time حذف شوند.
- اسکن ایمیجها: از ابزارهای اسکن آسیبپذیری ایمیج (مانند Trivy، Clair یا اسکنر داخلی Docker Hub) برای شناسایی و رفع آسیبپذیریها استفاده کنید.
- استفاده از ایمیجهای پایه کوچک و امن: از ایمیجهای پایه مانند Alpine یا Slim برای کاهش حجم و سطح حمله (attack surface) استفاده کنید (مثلاً
- کاربران غیر root در کانتینر:
همیشه کانتینرهای خود را با یک کاربر غیر root اجرا کنید. این کار به کاهش آسیب در صورت به خطر افتادن کانتینر کمک میکند.
services: app: image: myapp:latest user: 1000:1000 # اجرای کانتینر با uid:gid غیر root - محدودیت منابع:
همانطور که قبلاً بحث شد، محدودیتگذاری برای CPU و حافظه با استفاده از
deploy.resources.limitsبرای جلوگیری از حملات DoS (Denial of Service) یا مصرف بیش از حد منابع توسط یک کانتینر خراب ضروری است. - پیکربندی شبکه امن:
فقط پورتهایی را که واقعاً نیاز دارید به دنیای بیرون (میزبان) مپ کنید. از شبکههای سفارشی برای جداسازی سرویسها استفاده کنید و مطمئن شوید که فایروال سیستم میزبان، ترافیک ورودی را به درستی فیلتر میکند.
ملاحظات عملکردی و پایداری برای پروداکشن
- استفاده از Docker Compose در پروداکشن:
Docker Compose به تنهایی برای استقرارهای پروداکشن در مقیاس بزرگ توصیه نمیشود. این ابزار Load Balancing، Self-healing و مدیریت Rollout/Rollback را به صورت بومی ارائه نمیدهد. برای پروداکشن، پلتفرمهای ارکستراسیون کانتینر مانند Kubernetes یا Docker Swarm مناسبتر هستند.
با این حال، برای برنامههای کوچک، microserviceهای ساده، یا سرورهای توسعه/staging، Compose میتواند به عنوان یک راهحل استقرار “bare metal” مؤثر باشد.
اگر از Compose در پروداکشن استفاده میکنید، آن را با ابزارهای دیگری مانند Nginx به عنوان Reverse Proxy و Load Balancer برای توزیع ترافیک به نمونههای اسکیلشده کانتینرها، و یک ابزار monitoring/logging جامع ترکیب کنید.
- استراتژی Log Management:
در پروداکشن، لاگهای کانتینر باید به یک سیستم مرکزی مدیریت لاگ (مانند ELK Stack, Grafana Loki, Splunk) ارسال شوند. از
loggingdriver در Compose برای پیکربندی این ارسال استفاده کنید.services: app: image: myapp:latest logging: driver: "json-file" # پیشفرض، لاگ را به فایل json مینویسد # driver: "syslog" # مثال برای ارسال به syslog # options: # syslog-address: "udp://127.0.0.1:514" - پایداری دادهها و بکآپ:
برای پایگاههای داده و سرویسهایی که دادههای مهم را ذخیره میکنند، از Named Volumes استفاده کنید و استراتژیهای بکآپ منظم و بازیابی فاجعه (Disaster Recovery) را پیادهسازی کنید.
- توسعه مداوم/استقرار مداوم (CI/CD):
یک Pipeline CI/CD راهاندازی کنید که به صورت خودکار ایمیجهای داکر را بسازد، تستها را اجرا کند و برنامه را استقرار دهد. این کار فرآیند استقرار را قابل اعتمادتر و خودکارتر میکند.
انتقال از توسعه به پروداکشن با Docker Compose نیاز به برنامهریزی دقیق و در نظر گرفتن ملاحظات امنیتی و عملکردی دارد. در حالی که Compose ابزاری عالی برای شروع است، برای سیستمهای بزرگتر و حیاتیتر، سرمایهگذاری در پلتفرمهای ارکستراسیون پیشرفتهتر ضروری است.
جمعبندی و گامهای بعدی: تسلط بر اکوسیستم Docker Compose
در این راهنمای جامع، ما سفر خود را از اولین خطوط یک فایل docker-compose.yml تا اجرای موفقیتآمیز سرویسهای چندگانه و پیچیدگیهای مرتبط با آن را پیمودیم. شما اکنون با ساختار اصلی Docker Compose، نحوه تعریف سرویسها، مدیریت متغیرهای محیطی، مپ کردن پورتها، و تفاوتهای کلیدی بین image و build آشنا هستید. همچنین، به عمق مدیریت وابستگیها با depends_on و تضمین سلامت سرویسها با healthcheck پرداختیم، که برای پایداری برنامههای میکروسرویسی حیاتی است.
در ادامه، اهمیت شبکهبندی برای ارتباطات بین سرویسی، از شبکههای پیشفرض Bridge گرفته تا شبکههای سفارشی و خارجی، مورد بررسی قرار گرفت. در بخش ذخیرهسازی دادهها، تفاوتها و کاربردهای Bind Mounts و Named Volumes را آموختیم، که هر کدام برای سناریوهای خاص توسعه و پایداری دادهها ضروری هستند. مبحث اسکیلینگ و مدیریت منابع، راهکارهایی را برای افزایش کارایی و کنترل مصرف CPU و حافظه در اختیار شما قرار داد و در نهایت، بهینهسازی فرآیند توسعه و دیباگینگ با استفاده از Bind Mounts و فایلهای Compose چندگانه را بررسی کردیم.
در آخرین بخش، نکات امنیتی و ملاحظات مربوط به انتقال یک پروژه Docker Compose از محیط توسعه به محیط پروداکشن، هرچند به صورت مقدماتی، ارائه شد. این بخش تأکید کرد که Docker Compose به تنهایی برای استقرارهای بزرگ پروداکشن ایدهآل نیست، اما با رعایت اصول امنیتی و عملکردی، میتواند در سناریوهای خاص مورد استفاده قرار گیرد.
گامهای بعدی برای تسلط بر Docker Compose:
- تمرین و آزمایش: بهترین راه برای تسلط بر Docker Compose، نوشتن پروژههای واقعی و آزمایش با تنظیمات مختلف است. سعی کنید یک برنامه وب شامل Front-end (مثل React/Vue), Back-end (مثل Node.js/Python/Go) و یک پایگاه داده (مثل PostgreSQL/MongoDB) را با Compose راهاندازی کنید.
- پیکربندیهای پیشرفته
docker-compose.yml:- Extends: استفاده از
extendsبرای به اشتراکگذاری پیکربندیهای مشترک بین چندین فایل Compose یا سرویس. - Configs و Secrets: مطالعه عمیقتر قابلیتهای
configsوsecrets(به ویژه در Swarm Mode) برای مدیریت امنتر پیکربندی و اطلاعات حساس. - Logging Drivers: آزمایش با درایورهای لاگگیری مختلف (مانند
syslog،fluentd،awslogs) برای ارسال لاگها به سیستمهای متمرکز.
- Extends: استفاده از
- ابزارهای مرتبط:
- Reverse Proxies و Load Balancers: یادگیری نحوه ادغام Nginx یا Traefik با Docker Compose برای مسیریابی ترافیک و Load Balancing به سرویسهای اسکیلشده.
- Monitoring و Alerting: راهاندازی ابزارهایی مانند Prometheus و Grafana در کنار Compose برای نظارت بر عملکرد کانتینرها و ایجاد هشدار.
- یادگیری ارکستراسیون:
درک کنید که چه زمانی Docker Compose به تنهایی کافی نیست و به ابزارهای ارکستراسیون کانتینر مانند Docker Swarm (که Compose میتواند فایلهای نسخه 3 را برای آن به کار ببرد) یا Kubernetes نیاز دارید. این پلتفرمها برای مدیریت کانتینرها در مقیاس پروداکشن و ایجاد قابلیتهای پیشرفتهتر مانند Self-healing، Auto-scaling و Rollout/Rollback طراحی شدهاند.
- بهینهسازی Dockerfileها:
همیشه در تلاش برای بهینهسازی Dockerfileهای خود باشید تا ایمیجهای کوچکتر، سریعتر و امنتری تولید کنید. این شامل استفاده از Multi-stage builds، کش لایهها، و حذف فایلهای غیرضروری است.
Docker Compose یک ابزار فوقالعاده کاربردی در جعبه ابزار هر توسعهدهنده یا مهندس DevOps است. با تسلط بر آن، میتوانید محیطهای توسعه قدرتمندی ایجاد کنید، فرآیندهای تست را خودکار سازید و گامهای اولیه را برای استقرار برنامههای کانتینری در مقیاسهای مختلف بردارید. مسیر تسلط بر اکوسیستم Docker بیپایان است، اما با این دانش پایه و رهنمودها، شما به خوبی برای شروع آمادهاید.
“تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT”
"تسلط به برنامهنویسی پایتون با هوش مصنوعی: آموزش کدنویسی هوشمند با ChatGPT"
"با شرکت در این دوره جامع و کاربردی، به راحتی مهارتهای برنامهنویسی پایتون را از سطح مبتدی تا پیشرفته با کمک هوش مصنوعی ChatGPT بیاموزید. این دوره، با بیش از 6 ساعت محتوای آموزشی، شما را قادر میسازد تا به سرعت الگوریتمهای پیچیده را درک کرده و اپلیکیشنهای هوشمند ایجاد کنید. مناسب برای تمامی سطوح با زیرنویس فارسی حرفهای و امکان دانلود و تماشای آنلاین."
ویژگیهای کلیدی:
بدون نیاز به تجربه قبلی برنامهنویسی
زیرنویس فارسی با ترجمه حرفهای
۳۰ ٪ تخفیف ویژه برای دانشجویان و دانش آموزان