نحوه نوشتن داکر کامپوز
1403/12/01

نحوه نوشتن داکر کامپوز

برای نوشتن یک فایل Docker Compose، باید ابتدا ساختار فایل YAML را یاد بگیرید. در اینجا یک فهرست کامل از تنظیمات و بخش‌های مختلف در فایل docker-compose.yml آورده شده است:

1. نسخه (version)

نسخه‌ای که از Docker Compose استفاده می‌کنید. نسخه‌ها معمولا به صورت 3.x یا 2.x هستند.

version: '3.8'

2. خدمات (services)

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

مثال:

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  db:
    image: postgres:latest
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    volumes:
      - db_data:/var/lib/postgresql/data

3. شبکه‌ها (networks)

اگر می‌خواهید شبکه‌های خاصی برای کانتینرها بسازید، می‌توانید آنها را در این بخش تعریف کنید.

مثال:

networks:
  frontend:
  backend:

4. حجم‌ها (volumes)

برای ذخیره‌سازی داده‌ها، می‌توانید از حجم‌ها استفاده کنید تا داده‌ها حتی پس از توقف یا حذف کانتینر باقی بمانند.

مثال:

volumes:
  db_data:
  logs:

هر سرویس در فایل docker-compose.yml می‌تواند مجموعه‌ای از مقادیر مختلف داشته باشد که به Docker Compose نحوه‌ی پیکربندی و اجرای کانتینر را اعلام می‌کند. در ادامه مقادیر اصلی که هر سرویس می‌تواند داشته باشد آورده شده است:

1. image

  • تصویری که باید برای سرویس استفاده شود. اگر Dockerfile دارید، به جای آن می‌توانید از build استفاده کنید.
  • مثال:
    image: nginx:latest
    

2. build

  • برای ساخت یک تصویر Docker از یک دایرکتوری خاص (معمولاً جایی که Dockerfile قرار دارد) استفاده می‌شود.
  • مثال:
    build:
      context: .
      dockerfile: Dockerfile
    

3. command

  • دستوری که هنگام راه‌اندازی کانتینر اجرا می‌شود. این دستور به عنوان دستور پیش‌فرض در کانتینر اجرا خواهد شد.
  • مثال:
    command: ["npm", "start"]
    

4. entrypoint

  • مانند command است، اما این دستور به صورت پیش‌فرض هنگام راه‌اندازی کانتینر اجرا می‌شود و از دستور پیش‌فرض در تصویر (اگر باشد) جایگزین می‌کند.
  • مثال:
    entrypoint: ["python", "app.py"]
    

5. environment

  • متغیرهای محیطی که باید برای کانتینر تنظیم شوند.
  • مثال:
    environment:
      - NODE_ENV=production
      - APP_SECRET=mysecretkey
    

6. ports

  • پورت‌های کانتینر که به ماشین میزبان متصل می‌شوند. این مقادیر به شما امکان می‌دهند تا پورت‌های خاصی از کانتینر را به پورت‌های میزبان نگاشت کنید.
  • مثال:
    ports:
      - "8080:80"    # پورت 80 در کانتینر به پورت 8080 در میزبان متصل می‌شود
    

7. volumes

  • برای نگهداری داده‌ها یا اشتراک‌گذاری داده‌ها بین کانتینرها استفاده می‌شود.
  • مثال:
    volumes:
      - ./data:/data    # پوشه data از میزبان به پوشه data در کانتینر نگاشت می‌شود
    

8. depends_on

  • تعیین ترتیب راه‌اندازی کانتینرها. این گزینه مشخص می‌کند که یک سرویس به سرویس دیگری وابسته است و باید ابتدا راه‌اندازی شود.
  • مثال:
    depends_on:
      - db
    

9. restart

  • تنظیم سیاست برای راه‌اندازی مجدد کانتینر در صورت خرابی.
  • مقادیر ممکن: no, always, unless-stopped, on-failure
  • مثال:
    restart: always
    

10. networks

  • تعیین شبکه‌هایی که سرویس به آنها متصل می‌شود.
  • مثال:
    networks:
      - backend
      - frontend
    

11. healthcheck

  • برای تنظیم بررسی وضعیت سرویس استفاده می‌شود. شما می‌توانید بررسی کنید که آیا سرویس در حال اجراست یا نه.
  • مثال:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      retries: 3
    

12. cpu و mem

  • محدود کردن منابع سیستم (CPU، حافظه) برای سرویس.
  • مثال:
    deploy:
      resources:
        limits:
          memory: 500M
          cpus: "0.5"
    

13. labels

  • برای اضافه کردن برچسب‌هایی به کانتینر و خدمات. این برچسب‌ها ممکن است برای مدیریت و نظارت بر سرویس‌ها استفاده شوند.
  • مثال:
    labels:
      - "com.example.version=1.0"
    

14. extra_hosts

  • برای اضافه کردن ورودی‌های خاص به فایل /etc/hosts کانتینر استفاده می‌شود.
  • مثال:
    extra_hosts:
      - "example.com:93.184.216.34"
    

15. user

  • مشخص کردن کاربری که کانتینر تحت آن اجرا شود.
  • مثال:
    user: "1000:1000"
    

16. ulimits

  • محدود کردن منابع سیستم مانند فایل‌های باز و پردازش‌ها.
  • مثال:
    ulimits:
      nproc: 65535
    

17. logging

  • تنظیمات مربوط به لاگ‌ها و نحوه‌ی ذخیره و ارسال آنها.
  • مثال:
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
    

18. cap_add و cap_drop

  • اضافه کردن یا حذف قابلیت‌های خاص از کانتینر.
  • مثال:
    cap_add:
      - NET_ADMIN
    cap_drop:
      - MKNOD
    

19. devices

  • دسترسی به دستگاه‌های خاص در میزبان از طریق کانتینر.
  • مثال:
    devices:
      - "/dev/sda:/dev/sda"
    

نمونه کامل یک سرویس

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    environment:
      - ENV=production
    restart: always
    networks:
      - frontend
    depends_on:
      - db
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      retries: 3
    logging:
      driver: "json-file"
      options:
        max-size: "10m"

version

اینها مقادیر و تنظیمات اصلی هستند که می‌توانید برای هر سرویس در Docker Compose استفاده کنید.

نسخه‌ای که در فایل Docker Compose استفاده می‌شود معمولاً یکی از نسخه‌های 2.x یا 3.x است. این نسخه‌ها در Docker Compose ویژگی‌ها و قابلیت‌های مختلفی را در اختیار شما می‌گذارند. در زیر انواع نسخه‌های مختلف و ویژگی‌های آنها آورده شده است:

1. نسخه 1 (version: '1')

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

2. نسخه 2 (version: '2')

  • این نسخه ویژگی‌های جدیدتری را نسبت به نسخه 1 معرفی کرده است و از آن زمان به بعد در بسیاری از پروژه‌ها مورد استفاده قرار می‌گیرد.
  • این نسخه از شبکه‌ها و حجم‌های اختصاصی پشتیبانی می‌کند.
  • امکان پیکربندی متغیرهای محیطی (environment) برای سرویس‌ها و همچنین معرفی برخی ویژگی‌ها برای سیستم‌های تولید مانند depends_on و restart در این نسخه وجود دارد.

3. نسخه 3 (version: '3')

  • نسخه 3 به طور عمده برای Docker Swarm و استفاده در محیط‌های تولید طراحی شده است.
  • این نسخه بیشتر بر روی سرویس‌های مقیاس‌پذیر و استفاده در حالت cluster تمرکز دارد.
  • در این نسخه، ویژگی‌هایی مثل deploy, replicas, mode و resources به آن اضافه شده‌اند.
  • نسخه 3.x به طور گسترده در پروژه‌های Docker Compose برای محیط‌های تولید و کشاورزی (cloud) استفاده می‌شود.

4. نسخه 3.7 و بالاتر (version: '3.x')

  • هر نسخه جدیدتر از 3.x بهبودهایی مانند قابلیت‌های بیشتر در تعامل با Swarm و بهینه‌سازی‌های مرتبط با منابع و توزیع به همراه دارد.
  • برای استفاده در محیط‌های تولید و مقیاس‌پذیر مناسب است.

5. نسخه 2.x

  • نسخه 2.x شامل ویژگی‌های اضافی مانند external networks و همچنین گزینه‌های پیشرفته‌تر برای تنظیمات volume است.

انتخاب نسخه مناسب:

  • اگر برای محیط تولید (production) یا Docker Swarm کار می‌کنید، بهتر است از نسخه‌های 3.x (مثلاً 3.8) استفاده کنید.
  • برای توسعه و محیط‌های ساده‌تر که نیاز به ویژگی‌های پیشرفته ندارند، نسخه‌های 2.x می‌توانند مناسب باشند.

مثال از نسخه‌های مختلف:

version: '3.8'    # مناسب برای محیط تولید با Docker Swarm
version: '2'      # مناسب برای محیط‌های ساده‌تر
version: '3.0'    # نسخه 3 برای مقیاس‌پذیری و Docker Swarm

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


مورد 1 که در لیست مقادیر یک سرویس در فایل docker-compose.yml اشاره شده، image است.

image

در Docker Compose، image مشخص می‌کند که سرویس (کانتینر) از چه Docker Image‌ای ساخته شود. Docker Image یک تصویر از نرم‌افزار است که تمام کدها، کتابخانه‌ها، ابزارها، تنظیمات و تنظیمات محیطی مورد نیاز برای اجرای یک برنامه را شامل می‌شود. شما می‌توانید این تصاویر را از Docker Hub، Registry‌های خصوصی، یا از یک Dockerfile محلی بسازید.

سینتکس:

image: <image_name>:<tag>
  • image_name: نام Docker image که معمولاً به صورت <username>/<image> است. مثلاً برای استفاده از Nginx به عنوان وب سرور، می‌توانید از nginx به عنوان نام تصویر استفاده کنید.
  • tag (اختیاری): نسخه‌ای از تصویر. به طور پیش‌فرض، اگر tag مشخص نشود، latest در نظر گرفته می‌شود. اگر نسخه خاصی مد نظر باشد، می‌توان آن را مشخص کرد. مثلاً nginx:1.19 به معنای استفاده از نسخه 1.19 از Nginx است.

مثال‌ها

1. استفاده از تصویر عمومی از Docker Hub:

version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"

در این مثال:

  • image: nginx:latest به این معناست که سرویس web از تصویر عمومی Nginx که در Docker Hub موجود است و نسخه latest آن را استفاده خواهد کرد.
  • latest به طور پیش‌فرض آخرین نسخه منتشر شده از Nginx را دریافت می‌کند.

2. استفاده از تصویر با نسخه خاص:

version: '3.8'

services:
  web:
    image: nginx:1.19
    ports:
      - "8080:80"

در این مثال:

  • image: nginx:1.19 به این معناست که سرویس web از نسخه 1.19 تصویر Nginx استفاده خواهد کرد.

3. استفاده از تصویر با شناسه کامل:

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

version: '3.8'

services:
  web:
    image: myusername/myapp:1.0
    ports:
      - "8080:80"

در این مثال:

  • myusername/myapp:1.0 یک تصویر خصوصی است که توسط کاربر myusername بر روی Docker Hub یا یک رجیستری خصوصی بارگذاری شده است.
  • 1.0 نسخه‌ای است که در اینجا مشخص شده است.

4. استفاده از تصویر از یک رجیستری خصوصی:

version: '3.8'

services:
  web:
    image: registry.example.com/myapp:latest
    ports:
      - "8080:80"

در این مثال:

  • registry.example.com/myapp:latest به یک رجیستری خصوصی به نام registry.example.com اشاره می‌کند که تصویر myapp در آن قرار دارد.
  • latest آخرین نسخه از این تصویر را دریافت می‌کند.

5. استفاده از Dockerfile برای ساخت تصویر:

به جای اینکه از یک تصویر آماده استفاده کنید، می‌توانید از یک Dockerfile برای ساخت تصویر استفاده کنید. در این حالت، به جای image از build استفاده می‌شود.

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"

در این مثال:

  • از دستور build به جای image استفاده شده است.
  • context به دایرکتوری اشاره دارد که در آن Dockerfile قرار دارد (در اینجا، همان دایرکتوری فعلی است که با . نشان داده شده).
  • با استفاده از dockerfile: Dockerfile می‌توانید نام فایل Dockerfile را مشخص کنید (اگر نام دیگری به جز Dockerfile داشته باشد).
  • این دستور Docker Compose را مجبور می‌کند تا از Dockerfile موجود یک تصویر بسازد و سپس آن را برای کانتینر اجرا کند.

زمانی که از image استفاده می‌کنیم:

  • زمانی که تصویر از قبل ساخته شده و در Docker Hub یا یک رجیستری خصوصی ذخیره شده باشد، می‌توان به سادگی از آن استفاده کرد.
  • به عنوان مثال، می‌توانید از تصاویر آماده‌ای مانند nginx, mysql, redis و غیره استفاده کنید.
  • در صورتی که بخواهید تصویر را خودتان بسازید (مثلاً اگر تغییراتی در تنظیمات نرم‌افزار یا برنامه خود داده‌اید)، باید از دستور build به جای image استفاده کنید.

جمع‌بندی:

  • image مشخص می‌کند که برای هر سرویس باید از چه Docker Image‌ای استفاده شود.
  • این تصویر می‌تواند از Docker Hub یا یک رجیستری خصوصی باشد.
  • اگر شما نیاز دارید که تصویری خاص را بسازید، می‌توانید از Dockerfile خود استفاده کنید.

Mirror Registries

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

مزایای استفاده از ریجیستری‌های محلی:

  1. افزایش سرعت دسترسی: به دلیل نزدیکی سرورها به ایران، بارگذاری و دریافت تصاویر Docker سریع‌تر و پایدارتر خواهد بود.
  2. کاهش مشکلات تحریم‌ها: به دلیل تحریم‌های بین‌المللی، دسترسی به Docker Hub برای کاربران ایرانی ممکن است دچار اختلال یا محدودیت شود. استفاده از ریجیستری‌های محلی می‌تواند این مشکلات را برطرف کند.
  3. استفاده از منابع محلی: استفاده از منابع محلی باعث کاهش بار شبکه و استفاده بهینه از زیرساخت‌های داخلی می‌شود.

ریجیستری‌های Docker در ایران

در حال حاضر، برخی از شرکت‌ها و سرویس‌دهندگان ایرانی اقدام به راه‌اندازی Docker Mirror Registries کرده‌اند که به کاربران ایرانی این امکان را می‌دهند که به راحتی تصاویر Docker را از منابع داخلی دریافت کنند.

1. Registry.ir

  • Registry.ir یکی از معروف‌ترین و معتبرترین ریجیستری‌های محلی در ایران است که توسط مرکز داده‌های داخلی در کشور راه‌اندازی شده است.
  • این ریجیستری برای استفاده از Docker Hub به عنوان Mirror ساخته شده و به طور خاص برای کاربران ایرانی طراحی شده است.
  • آدرس: https://registry.ir

2. Docker.ir

  • Docker.ir یک ریجیستری محلی دیگر است که برای بهبود دسترسی به Docker Hub در ایران راه‌اندازی شده است.
  • این سرویس نیز به صورت Mirror از Docker Hub عمل می‌کند و برای تسهیل فرایند دانلود و بارگذاری تصاویر Docker برای کاربران ایرانی طراحی شده است.
  • آدرس: https://docker.ir

3. Tebyan Registry

  • Tebyan (تبیان) نیز یکی دیگر از پروژه‌های بزرگ داخلی است که در تلاش است تا سرویس‌های متنوعی از جمله یک ریجیستری Docker را در دسترس کاربران ایرانی قرار دهد.
  • آدرس: https://registry.tebyan.net

4. NiaRex Registry

  • NiaRex یک پلتفرم مبتنی بر Docker است که برخی خدمات مرتبط با مدیریت و به اشتراک‌گذاری Docker Image‌ها را فراهم می‌آورد.
  • آدرس: https://docker.niarex.com

چگونه از ریجیستری‌های محلی استفاده کنیم؟

برای استفاده از این ریجیستری‌های محلی به راحتی می‌توانید در دستور docker pull یا docker push به جای استفاده از آدرس Docker Hub، آدرس یکی از این ریجیستری‌های محلی را وارد کنید.

مثال:

برای کشیدن یک تصویر از Registry.ir، به این صورت عمل می‌کنید:

docker pull registry.ir/nginx:latest

و برای ارسال یک تصویر به ریجیستری محلی:

docker push registry.ir/myapp:latest

نکات مهم:

  • نصب و پیکربندی: در برخی مواقع ممکن است لازم باشد تا تنظیمات Docker خود را برای استفاده از این ریجیستری‌ها تغییر دهید. معمولاً این تغییرات شامل پیکربندی فایل Docker config یا اضافه کردن Mirror URLs به تنظیمات Docker می‌شود.
  • نسخه‌ها و هماهنگی‌ها: تصاویر موجود در این ریجیستری‌های محلی معمولاً به‌روز هستند، اما ممکن است برخی از نسخه‌ها یا تصاویر خاص دیرتر از Docker Hub در دسترس قرار گیرند.

نتیجه‌گیری:

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


مورد 2 که در لیست مقادیر یک سرویس در فایل docker-compose.yml به آن اشاره شده، build است. این دستور برای ساخت یک Docker Image از یک Dockerfile استفاده می‌شود.

build

در صورتی که شما بخواهید یک Docker Image سفارشی بسازید (برای مثال اگر نیاز به تنظیمات خاص، نرم‌افزارهای اضافی یا تغییرات در کد پروژه خود دارید)، می‌توانید از دستور build در فایل docker-compose.yml استفاده کنید. این دستور به Docker Compose می‌گوید که به جای استفاده از یک تصویر آماده (مانند آنهایی که از Docker Hub بارگیری می‌کنید)، باید از یک Dockerfile محلی برای ساختن تصویر استفاده کند.

سینتکس

build:
  context: <path>
  dockerfile: <Dockerfile path>  # این گزینه اختیاری است
  args:
    - <ARG_NAME>=<value>  # برای متغیرهای build

توضیحات مقادیر:

  1. context:

    • context مسیر دایرکتوری است که Docker باید از آنجا شروع به ساختن تصویر کند. این دایرکتوری شامل فایل‌های مربوط به پروژه و Dockerfile شما خواهد بود.
    • معمولاً context به دایرکتوری فعلی پروژه اشاره می‌کند که می‌تواند با . (نقطه) مشخص شود.
    • در واقع، context تعیین می‌کند که چه فایل‌هایی به Docker ارسال می‌شود تا در زمان ساخت تصویر در دسترس باشند.

    مثال:

    context: ./app  # استفاده از دایرکتوری 'app' برای ساختن تصویر
    
  2. dockerfile:

    • این گزینه اختیاری است و برای زمانی استفاده می‌شود که نام یا مسیر Dockerfile شما غیر از Dockerfile باشد.
    • به طور پیش‌فرض، Docker به دنبال فایل Dockerfile در مسیر context می‌گردد، اما در صورت لزوم می‌توانید نام یا مسیر دیگری را مشخص کنید.

    مثال:

    dockerfile: ./path/to/Dockerfile
    
  3. args:

    • این گزینه برای ارسال آرگومان‌های build به Dockerfile استفاده می‌شود. اگر در Dockerfile از دستور ARG برای تعریف متغیر استفاده کرده باشید، می‌توانید مقادیر آن را از طریق این گزینه ارسال کنید.

    مثال:

    args:
      - BUILD_VERSION=1.0
    

مثال‌ها:

1. ساخت Docker Image از یک Dockerfile ساده:

در این مثال، Docker Compose از Dockerfile موجود در دایرکتوری فعلی (با .) استفاده می‌کند و تصویر را بر اساس آن می‌سازد.

version: '3.8'

services:
  web:
    build:
      context: .  # دایرکتوری فعلی برای ساختن تصویر
    ports:
      - "8080:80"

در اینجا:

  • context: . به این معنی است که Dockerfile و تمامی فایل‌های پروژه باید از دایرکتوری جاری گرفته شوند.
  • Docker Compose در اینجا از Dockerfile موجود در دایرکتوری فعلی برای ساختن تصویر استفاده می‌کند.

2. استفاده از Dockerfile در یک دایرکتوری خاص:

فرض کنید فایل Dockerfile در یک دایرکتوری خاص به نام ./myapp قرار دارد. می‌توانید از آن به این شکل استفاده کنید:

version: '3.8'

services:
  app:
    build:
      context: ./myapp  # مسیر دایرکتوری که Dockerfile در آن قرار دارد
      dockerfile: Dockerfile.dev  # اگر نام Dockerfile متفاوت باشد
    ports:
      - "3000:3000"

در اینجا:

  • context: ./myapp به Docker می‌گوید که باید تمام فایل‌های پروژه را از دایرکتوری myapp بارگذاری کند.
  • dockerfile: Dockerfile.dev به Docker Compose می‌گوید که باید از فایل Dockerfile.dev برای ساختن تصویر استفاده کند، نه از فایل پیش‌فرض Dockerfile.

3. ارسال آرگومان‌های Build:

اگر Dockerfile شما دارای آرگومان‌هایی برای ساخت تصویر باشد (مثلاً برای تنظیم نسخه یا نوع محیط) می‌توانید از args استفاده کنید.

فرض کنید Dockerfile شما دارای یک دستور ARG به شکل زیر است:

ARG BUILD_VERSION
RUN echo "Building version $BUILD_VERSION"

برای ارسال آرگومان به Dockerfile از طریق Docker Compose، از گزینه args استفاده می‌کنید:

version: '3.8'

services:
  app:
    build:
      context: .  # دایرکتوری جاری
      args:
        BUILD_VERSION: "1.0"
    ports:
      - "8080:80"

در اینجا:

  • args مقدار BUILD_VERSION را به Dockerfile ارسال می‌کند که در آن متغیر BUILD_VERSION استفاده خواهد شد.

4. ساخت تصویر از یک Git Repository:

شما همچنین می‌توانید از یک مخزن Git به عنوان context برای ساختن تصویر استفاده کنید. در این صورت Docker Compose تصویر را از کدهای موجود در مخزن Git می‌سازد.

version: '3.8'

services:
  app:
    build:
      context: https://github.com/user/repository.git
    ports:
      - "8080:80"

در اینجا:

  • context: https://github.com/user/repository.git به این معناست که Docker از مخزن Git موجود در این آدرس برای ساخت تصویر استفاده می‌کند.

مزایای استفاده از build:

  1. ساخت تصاویر سفارشی: زمانی که نیاز به پیکربندی خاص یا تغییراتی در محیط نرم‌افزاری دارید، می‌توانید با استفاده از Dockerfile خود تصویر مورد نظر را بسازید.
  2. انعطاف‌پذیری: از آنجا که می‌توانید فایل‌های خاص و تنظیمات مختلفی را از طریق Dockerfile وارد کنید، می‌توانید یک تصویر دقیقا مطابق با نیاز خود بسازید.
  3. اتوماتیک‌سازی فرآیند ساخت: با استفاده از docker-compose build می‌توانید فرآیند ساخت را خودکار کنید و به سادگی محیط‌های مختلف را مدیریت کنید.

نتیجه‌گیری:

دستور build در Docker Compose به شما این امکان را می‌دهد که تصاویر Docker را از طریق یک Dockerfile بسازید. این روش برای پروژه‌هایی که نیاز به تنظیمات خاص دارند، بسیار مفید است و می‌تواند به شما در بهبود فرآیند توسعه و پیاده‌سازی کمک کند.


Dockerfile نحوه نوشتن

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

ساختار پایه Dockerfile

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

  1. FROM: تصویر پایه‌ای که می‌خواهید روی آن کار کنید.
  2. RUN: دستوراتی که باید در زمان ساخت تصویر اجرا شوند.
  3. COPY و ADD: برای کپی کردن فایل‌ها از دایرکتوری‌های محلی به داخل تصویر.
  4. WORKDIR: مسیر کاری که دستورات بعدی در آن اجرا خواهند شد.
  5. CMD: دستوری که هنگام اجرای کانتینر اجرا می‌شود.
  6. EXPOSE: پورت‌هایی که کانتینر به آنها گوش می‌دهد.
  7. ENV: متغیرهای محیطی که در زمان ساخت یا اجرای کانتینر تنظیم می‌شوند.

مثال از یک Dockerfile ساده

در اینجا یک Dockerfile ساده برای یک اپلیکیشن Node.js آورده شده است:

Dockerfile برای Node.js

# 1. استفاده از یک تصویر پایه (Node.js)
FROM node:16

# 2. تنظیم دایرکتوری کاری در داخل کانتینر
WORKDIR /app

# 3. کپی کردن فایل‌های پکیج (package.json و package-lock.json)
COPY package*.json ./

# 4. نصب وابستگی‌ها
RUN npm install

# 5. کپی کردن باقی فایل‌های پروژه به داخل کانتینر
COPY . .

# 6. پورت‌های مورد نیاز
EXPOSE 3000

# 7. دستور برای شروع اپلیکیشن
CMD ["npm", "start"]

توضیحات:

  1. FROM node:16:

    • این دستور می‌گوید که تصویر پایه‌ای که می‌خواهیم از آن استفاده کنیم، نسخه 16 از Node.js است. Docker این تصویر را از Docker Hub دریافت می‌کند.
  2. WORKDIR /app:

    • این دستور به Docker می‌گوید که دایرکتوری کاری داخل کانتینر را به /app تغییر دهد. تمام دستورات بعدی در این دایرکتوری اجرا خواهند شد.
  3. COPY package*.json ./:

    • این دستور فایل‌های package.json و package-lock.json را از دایرکتوری محلی به دایرکتوری کاری کانتینر کپی می‌کند.
    • این فایل‌ها برای نصب وابستگی‌ها نیاز هستند.
  4. RUN npm install:

    • این دستور باعث می‌شود تا در زمان ساخت تصویر، وابستگی‌های تعریف شده در package.json نصب شوند.
  5. COPY . .:

    • این دستور تمام فایل‌ها و پوشه‌های موجود در دایرکتوری محلی را به دایرکتوری کاری کانتینر کپی می‌کند.
  6. EXPOSE 3000:

    • این دستور پورت 3000 را در کانتینر باز می‌کند، که به این معناست که اپلیکیشن شما باید از این پورت استفاده کند.
  7. CMD ["npm", "start"]:

    • این دستور به Docker می‌گوید که هنگام اجرای کانتینر، دستور npm start را اجرا کند که معمولاً برای شروع اپلیکیشن Node.js استفاده می‌شود.

مثال دیگر: Dockerfile برای یک اپلیکیشن Python (Flask)

در اینجا یک مثال از Dockerfile برای یک اپلیکیشن Flask در Python آورده شده است:

# 1. استفاده از یک تصویر پایه (Python)
FROM python:3.9-slim

# 2. تنظیم دایرکتوری کاری در داخل کانتینر
WORKDIR /app

# 3. کپی کردن فایل‌های پکیج
COPY requirements.txt .

# 4. نصب وابستگی‌ها
RUN pip install -r requirements.txt

# 5. کپی کردن باقی فایل‌های پروژه به داخل کانتینر
COPY . .

# 6. پورت‌های مورد نیاز
EXPOSE 5000

# 7. دستور برای شروع اپلیکیشن
CMD ["python", "app.py"]

توضیحات این Dockerfile:

  1. FROM python:3.9-slim:

    • تصویر پایه استفاده شده برای این اپلیکیشن، نسخه 3.9 از Python است که نسخه‌ای سبک و کم حجم از Python است.
  2. WORKDIR /app:

    • دایرکتوری کاری را داخل کانتینر به /app تنظیم می‌کند.
  3. COPY requirements.txt .:

    • فایل requirements.txt را که حاوی لیست وابستگی‌های Python است به دایرکتوری کاری داخل کانتینر کپی می‌کند.
  4. RUN pip install -r requirements.txt:

    • وابستگی‌های مورد نیاز اپلیکیشن را با استفاده از pip نصب می‌کند.
  5. COPY . .:

    • تمام فایل‌ها و پوشه‌ها از دایرکتوری محلی به دایرکتوری کاری کانتینر کپی می‌شوند.
  6. EXPOSE 5000:

    • پورت 5000 را برای کانتینر باز می‌کند، زیرا Flask به طور پیش‌فرض از این پورت استفاده می‌کند.
  7. CMD ["python", "app.py"]:

    • این دستور به Docker می‌گوید که هنگام اجرای کانتینر، دستور python app.py را اجرا کند، که اپلیکیشن Flask را راه‌اندازی می‌کند.

نکات اضافی:

  • RUN برای نصب وابستگی‌ها یا اجرای دستورات مختلف در زمان ساخت تصویر استفاده می‌شود.
  • COPY برای کپی کردن فایل‌ها و دایرکتوری‌ها به داخل تصویر استفاده می‌شود.
  • CMD دستوری است که هنگام اجرای کانتینر اجرا می‌شود.
  • EXPOSE برای اعلام پورت‌هایی که کانتینر به آن‌ها گوش می‌دهد استفاده می‌شود.
  • WORKDIR برای تنظیم دایرکتوری کاری کانتینر است.

نتیجه‌گیری:

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


در Docker Compose، گزینه command برای تنظیم دستوری است که هنگام اجرای کانتینر اجرا می‌شود. این دستور به صورت پیش‌فرض می‌تواند در فایل Dockerfile تعریف شده باشد (با استفاده از دستور CMD)، اما در Docker Compose شما می‌توانید آن را تغییر دهید یا دستور جدیدی برای اجرای کانتینر تنظیم کنید.

command

اگر می‌خواهید کانتینر را با دستور خاصی راه‌اندازی کنید، می‌توانید از command استفاده کنید. این گزینه دستوری را که باید هنگام اجرای کانتینر اجرا شود، مشخص می‌کند و جایگزین دستور CMD موجود در Dockerfile می‌شود.

سینتکس

services:
  <service_name>:
    command: <your_command>

مثال‌ها:

1. تغییر دستور پیش‌فرض در Dockerfile:

فرض کنید در Dockerfile شما از دستور CMD برای اجرای یک برنامه استفاده کرده‌اید. حالا می‌خواهید در Docker Compose دستور دیگری برای اجرای کانتینر تعیین کنید.

فرض کنید Dockerfile شما به این شکل است:

# Dockerfile
FROM python:3.9

WORKDIR /app

COPY . .

CMD ["python", "app.py"]

در اینجا دستور پیش‌فرض برای اجرای کانتینر python app.py است. حالا در فایل docker-compose.yml می‌توانید این دستور را تغییر دهید:

version: '3.8'

services:
  app:
    build:
      context: .
    command: python alternative.py  # دستور جدید برای اجرای کانتینر

در این مثال:

  • به جای اجرای python app.py که در Dockerfile تعریف شده بود، دستور python alternative.py اجرا خواهد شد.

2. اجرای چند دستور با استفاده از command:

در صورتی که نیاز به اجرای چند دستور در کانتینر دارید، می‌توانید از یک دستور شل مانند sh -c یا bash -c استفاده کنید:

version: '3.8'

services:
  app:
    build:
      context: .
    command: sh -c "echo 'Hello, World!' && python app.py"

در این مثال:

  • ابتدا پیام Hello, World! چاپ می‌شود و سپس python app.py اجرا خواهد شد.

3. استفاده از command برای تنظیم پارامترهای اضافی:

فرض کنید شما در Dockerfile خود دستور CMD را به این شکل دارید:

CMD ["python", "app.py"]

اما در Docker Compose می‌خواهید پارامترهایی به این دستور اضافه کنید:

version: '3.8'

services:
  app:
    build:
      context: .
    command: python app.py --debug

در اینجا:

  • به دستور پیش‌فرض python app.py پارامتر --debug اضافه شده است و کانتینر با این پارامتر اجرا خواهد شد.

نکات مهم:

  1. جایگزینی دستور CMD: زمانی که از command در Docker Compose استفاده می‌کنید، دستور موجود در Dockerfile (اگر موجود باشد) با دستور جدید جایگزین می‌شود.

  2. فرمت‌ها: شما می‌توانید دستور را به دو صورت array (ماتریس) یا string بنویسید:

    • Array: command: ["python", "app.py"]
    • String: command: "python app.py"
  3. استفاده از sh -c: برای اجرای چندین دستور یا تنظیم متغیرهای محیطی می‌توانید از sh -c یا bash -c استفاده کنید.

نتیجه‌گیری:

استفاده از command در Docker Compose به شما این امکان را می‌دهد که دستور اجرای کانتینر را تغییر دهید. این گزینه جایگزین دستور پیش‌فرض CMD در Dockerfile می‌شود و به شما امکان می‌دهد که رفتار کانتینر خود را بسته به نیاز پروژه تنظیم کنید.


در Docker Compose، گزینه environment برای تنظیم متغیرهای محیطی (environment variables) استفاده می‌شود. این متغیرها به کانتینرهای در حال اجرا ارسال می‌شوند و می‌توانند به برنامه‌های داخل کانتینر کمک کنند تا رفتار خود را بسته به محیطی که در آن اجرا می‌شوند، تنظیم کنند.

environment

services:
  <service_name>:
    environment:
      - <VARIABLE_NAME>=<VALUE>

یا می‌توانید از فرمت دیکشنری (کلید/مقدار) نیز استفاده کنید:

services:
  <service_name>:
    environment:
      <VARIABLE_NAME>: <VALUE>

مثال‌ها:

1. تنظیم متغیرهای محیطی ساده:

در این مثال، دو متغیر محیطی APP_ENV و DB_HOST به کانتینر ارسال می‌شوند.

version: '3.8'

services:
  app:
    image: my-app
    environment:
      - APP_ENV=production
      - DB_HOST=localhost

در اینجا:

  • APP_ENV=production و DB_HOST=localhost به عنوان متغیرهای محیطی در کانتینر تنظیم می‌شوند.
  • این متغیرها می‌توانند در برنامه شما (مثلاً در کد Python یا Node.js) استفاده شوند.

2. استفاده از فرمت کلید/مقدار:

در این روش، می‌توانید متغیرهای محیطی را به صورت یک دیکشنری (کلید/مقدار) تعریف کنید.

version: '3.8'

services:
  app:
    image: my-app
    environment:
      APP_ENV: production
      DB_HOST: localhost

این حالت دقیقاً مشابه حالت قبلی است، اما استفاده از فرمت دیکشنری خوانایی بهتری دارد.

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

برای مدیریت متغیرهای محیطی به صورت مرکزی و راحت‌تر، می‌توانید از فایل‌های .env استفاده کنید. در این حالت، مقادیر متغیرها از فایل .env بارگذاری می‌شوند و نیازی به ذکر دستی مقادیر در فایل docker-compose.yml نیست.

  • ابتدا فایل .env را در کنار فایل docker-compose.yml ایجاد کنید:
# .env
APP_ENV=production
DB_HOST=localhost
  • سپس در فایل docker-compose.yml از این متغیرها استفاده کنید:
version: '3.8'

services:
  app:
    image: my-app
    environment:
      - APP_ENV=${APP_ENV}
      - DB_HOST=${DB_HOST}

در اینجا:

  • متغیرهای محیطی به طور خودکار از فایل .env بارگذاری می‌شوند.
  • این روش کمک می‌کند که مقادیر حساس یا مقادیر پیکربندی را خارج از فایل docker-compose.yml نگه دارید.

4. استفاده از متغیرهای محیطی در Dockerfile:

در Dockerfile نیز می‌توان از متغیرهای محیطی که در Docker Compose تنظیم شده‌اند استفاده کرد. برای این کار می‌توانید از دستور ENV در Dockerfile استفاده کنید.

# Dockerfile
FROM node:16

# تنظیم متغیر محیطی در Dockerfile
ENV APP_ENV=production

WORKDIR /app
COPY . .

CMD ["npm", "start"]

در اینجا:

  • APP_ENV=production به عنوان متغیر محیطی در Dockerfile تنظیم شده است و می‌توانید از آن در اپلیکیشن خود استفاده کنید.

نکات مهم:

  1. دسترسی به متغیرهای محیطی: متغیرهای محیطی که از طریق Docker Compose به کانتینر ارسال می‌شوند، برای برنامه‌هایی که داخل کانتینر اجرا می‌شوند (مثل Node.js، Python، Java و غیره) قابل دسترس هستند. برای مثال، در Node.js می‌توانید از process.env.APP_ENV برای دسترسی به متغیر APP_ENV استفاده کنید.

  2. امنیت: مقادیر حساس مانند رمزعبور و کلیدهای API بهتر است در فایل .env نگهداری شوند و از قرار دادن این مقادیر به صورت مستقیم در فایل docker-compose.yml خودداری کنید. همچنین می‌توانید از ابزارهایی مثل Docker Secrets برای مدیریت امن‌تر اطلاعات حساس استفاده کنید.

  3. بارگذاری متغیرها از فایل: در صورتی که بخواهید مقادیر متغیرها را از فایل .env بارگذاری کنید، فایل .env باید در همان دایرکتوری که فایل docker-compose.yml قرار دارد، موجود باشد. Docker Compose به صورت خودکار فایل .env را بارگذاری می‌کند.

نتیجه‌گیری:

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


در Docker Compose، گزینه env_file به شما این امکان را می‌دهد که متغیرهای محیطی را از یک یا چند فایل بارگذاری کنید. این فایل‌ها می‌توانند شامل متغیرهای محیطی باشند که به کانتینرها ارسال می‌شوند و به شما این امکان را می‌دهند که مقادیر متغیرهای محیطی را در یک فایل جداگانه نگه‌داری کنید، به‌جای اینکه مقادیر را مستقیماً در فایل docker-compose.yml بنویسید.

env_file

services:
  <service_name>:
    env_file:
      - <path_to_env_file>

شما می‌توانید چندین فایل .env را وارد کنید، و Docker Compose همه آنها را بارگذاری خواهد کرد.

مثال‌ها:

1. استفاده از یک فایل .env

فرض کنید یک فایل .env داریم که متغیرهای محیطی آن به شکل زیر است:

# .env
APP_ENV=production
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=secret

سپس در فایل docker-compose.yml می‌توانید از این فایل برای بارگذاری متغیرهای محیطی استفاده کنید:

version: '3.8'

services:
  app:
    image: my-app
    env_file:
      - .env

در اینجا:

  • فایل .env شامل مقادیر متغیرهای محیطی است که به کانتینر ارسال می‌شوند.
  • این مقادیر به طور خودکار توسط Docker Compose بارگذاری شده و در داخل کانتینر در دسترس قرار خواهند گرفت.

2. استفاده از چندین فایل env_file

اگر بخواهید چندین فایل .env را بارگذاری کنید، می‌توانید لیستی از فایل‌ها را در گزینه env_file وارد کنید:

version: '3.8'

services:
  app:
    image: my-app
    env_file:
      - .env
      - .env.production

در اینجا:

  • Docker Compose اول فایل .env و سپس فایل .env.production را بارگذاری می‌کند.
  • اگر در هر دو فایل متغیری با همین نام وجود داشته باشد، مقدار متغیر از فایلی که بعد از فایل قبلی در لیست آمده، استفاده می‌شود (اولویت با آخرین فایل است).

3. استفاده از env_file با متغیرهای محلی

شما همچنین می‌توانید از فایل‌های env_file به‌صورت محلی استفاده کنید که در دایرکتوری‌های مختلف قرار دارند.

version: '3.8'

services:
  app:
    image: my-app
    env_file:
      - ./config/.env

در اینجا:

  • فایل .env از دایرکتوری ./config/ بارگذاری می‌شود.

4. ترکیب env_file و environment

در صورتی که هم از env_file و هم از environment استفاده کنید، Docker Compose مقادیر environment را بر مقادیر موجود در فایل env_file اولویت می‌دهد.

version: '3.8'

services:
  app:
    image: my-app
    env_file:
      - .env
    environment:
      DB_PASSWORD: custompassword

در اینجا:

  • اگر DB_PASSWORD در فایل .env وجود داشته باشد، مقدار custompassword که در بخش environment تعیین شده، از آن استفاده می‌شود.

نکات مهم:

  1. فرمت فایل .env: فایل‌های .env باید شامل جفت‌های کلید/مقدار باشند که به شکل زیر نوشته می‌شوند:

    KEY=VALUE
    

    همچنین، این فایل‌ها نباید شامل هیچ فضای خالی قبل یا بعد از علامت = باشند.

  2. بارگذاری مقادیر متغیرها: وقتی که از گزینه env_file استفاده می‌کنید، تمام متغیرهای داخل فایل‌های وارد شده به محیط کانتینر ارسال می‌شوند و به برنامه‌هایی که داخل کانتینر اجرا می‌شوند، قابل دسترسی خواهند بود.

  3. اولویت: اگر در فایل‌های مختلف .env متغیرهای مشابهی وجود داشته باشند، مقادیر آخرین فایل در اولویت قرار خواهند گرفت.

  4. دسترسی در داخل کانتینر: متغیرهای محیطی که از طریق env_file بارگذاری می‌شوند، برای برنامه‌های در حال اجرا داخل کانتینر قابل دسترسی هستند. برای مثال، در یک اپلیکیشن Python می‌توانید از os.environ برای دسترسی به این متغیرها استفاده کنید.

نتیجه‌گیری:

استفاده از env_file در Docker Compose باعث می‌شود که مدیریت متغیرهای محیطی ساده‌تر و تمیزتر شود. شما می‌توانید تمامی مقادیر حساس و پیکربندی‌ها را در فایل‌های جداگانه قرار دهید و آنها را از طریق docker-compose.yml به کانتینرها ارسال کنید. این روش به‌ویژه برای پروژه‌هایی که مقادیر پیکربندی متغیر دارند (مثل محیط‌های تولید، تست و توسعه) بسیار مفید است.


در Docker Compose، گزینه ports برای نقشه‌برداری (mapping) پورت‌های کانتینر به پورت‌های میزبان (host) استفاده می‌شود. این کار به شما این امکان را می‌دهد که بتوانید از بیرون به سرویس‌هایی که داخل کانتینر در حال اجرا هستند دسترسی پیدا کنید. معمولاً این مورد برای دسترسی به وب‌سایت‌ها، API‌ها، پایگاه داده‌ها یا هر سرویس دیگری که از شبکه نیاز به دسترسی به آن دارید، کاربرد دارد.

ports

services:
  <service_name>:
    ports:
      - "<host_port>:<container_port>"

در اینجا:

  • host_port: شماره پورت روی ماشین میزبان (کامپیوتر یا سرور) که می‌خواهید به آن دسترسی داشته باشید.
  • container_port: شماره پورت داخل کانتینر که سرویس شما در آن در حال اجرا است.

مثال‌ها:

1. نقشه‌برداری ساده پورت‌ها

فرض کنید شما یک سرویس وب داخل یک کانتینر دارید که بر روی پورت 80 اجرا می‌شود، و می‌خواهید از طریق پورت 8080 ماشین میزبان به آن دسترسی داشته باشید. در این صورت از گزینه ports به این شکل استفاده می‌کنید:

version: '3.8'

services:
  web:
    image: nginx
    ports:
      - "8080:80"

در اینجا:

  • 8080:80 به این معنی است که پورت 80 داخل کانتینر (که سرویس Nginx در آن در حال اجراست) به پورت 8080 ماشین میزبان نقشه‌برداری شده است.
  • وقتی که شما در مرورگر خود به http://localhost:8080 دسترسی پیدا کنید، درخواست به کانتینر ارسال شده و سرویس Nginx که در پورت 80 در داخل کانتینر اجرا می‌شود، به آن پاسخ خواهد داد.

2. نقشه‌برداری پورت‌های مختلف

شما می‌توانید چندین پورت را برای نقشه‌برداری به یک کانتینر تعریف کنید. مثلا اگر کانتینر شما به دو پورت مختلف نیاز داشته باشد:

version: '3.8'

services:
  app:
    image: my-app
    ports:
      - "8080:80"  # برای دسترسی به پورت 80 کانتینر از پورت 8080 میزبان
      - "443:443"  # برای دسترسی به پورت 443 کانتینر از پورت 443 میزبان

در اینجا:

  • پورت 80 داخل کانتینر به پورت 8080 میزبان نقشه‌برداری می‌شود.
  • پورت 443 داخل کانتینر به پورت 443 میزبان نقشه‌برداری می‌شود.

3. استفاده از پورت‌های تصادفی (Random Ports)

اگر بخواهید که Docker به طور خودکار یک پورت تصادفی را روی میزبان انتخاب کند، می‌توانید از سینتکس زیر استفاده کنید:

version: '3.8'

services:
  app:
    image: my-app
    ports:
      - "8080"  # Docker به طور خودکار پورت تصادفی را به پورت 8080 داخل کانتینر می‌نویسد

در اینجا:

  • Docker Compose به طور خودکار یک پورت تصادفی روی میزبان انتخاب می‌کند و آن را به پورت 8080 داخل کانتینر نقشه‌برداری می‌کند.

4. نقشه‌برداری پورت‌ها با حالت TCP یا UDP

در صورتی که شما نیاز به استفاده از پروتکل خاصی مانند TCP یا UDP داشته باشید، می‌توانید از این روش استفاده کنید. به‌طور پیش‌فرض، پورت‌ها به پروتکل TCP تخصیص می‌یابند، اما می‌توانید به صورت خاص پروتکل را تعیین کنید.

version: '3.8'

services:
  app:
    image: my-app
    ports:
      - "8080:80/tcp"  # پروتکل TCP
      - "12345:12345/udp"  # پروتکل UDP

در اینجا:

  • 8080:80/tcp به این معنی است که پورت 8080 میزبان به پورت 80 داخل کانتینر از نوع TCP نقشه‌برداری شده است.
  • 12345:12345/udp به این معنی است که پورت 12345 میزبان به پورت 12345 داخل کانتینر از نوع UDP نقشه‌برداری شده است.

نکات مهم:

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

  2. پورت‌های عمومی: اگر کانتینر شما سرویس‌های عمومی (مثل وب‌سایت یا API) را ارائه می‌دهد، می‌توانید از این روش برای دسترسی به آن‌ها از هر جایی (مثلاً از اینترنت) استفاده کنید.

  3. آدرس IP مخصوص: می‌توانید پورت‌ها را به آدرس IP خاصی از ماشین میزبان محدود کنید، به این صورت که فقط از آن IP به کانتینر دسترسی پیدا کنید. این کار می‌تواند امنیت شبکه را افزایش دهد.

نتیجه‌گیری:

گزینه ports در Docker Compose به شما این امکان را می‌دهد که پورت‌های داخل کانتینر را به پورت‌های میزبان نقشه‌برداری کنید. این امر برای دسترسی به سرویس‌ها و برنامه‌های داخل کانتینر از خارج از آن‌ها ضروری است و می‌توانید برای دسترسی به سرویس‌ها از پروتکل‌های مختلف (TCP، UDP) استفاده کنید.


در Docker Compose، گزینه volumes به شما این امکان را می‌دهد که داده‌ها را خارج از کانتینرها ذخیره کنید، یا داده‌ها را بین کانتینرهای مختلف به اشتراک بگذارید. استفاده از volumes به شما کمک می‌کند تا اطلاعات (مثل پایگاه داده‌ها، فایل‌های آپلود شده، پیکربندی‌ها و غیره) را حفظ کنید حتی اگر کانتینرها از سیستم حذف شوند یا دوباره راه‌اندازی شوند.

هدف اصلی volumes:

  1. نگهداری داده‌ها: زمانی که کانتینرها خاموش می‌شوند یا حذف می‌شوند، داده‌ها از دست نمی‌روند زیرا در فضای ذخیره‌سازی خارجی (در خارج از کانتینر) نگهداری می‌شوند.
  2. اشتراک‌گذاری داده‌ها: می‌توانید داده‌ها را بین کانتینرهای مختلف به اشتراک بگذارید.

سینتکس volumes در Docker Compose:

services:
  <service_name>:
    volumes:
      - <volume_name_or_path>:<container_path>

در اینجا:

  • volume_name_or_path: می‌تواند یک volume از نوع نام‌گذاری شده باشد (که توسط Docker مدیریت می‌شود) یا یک مسیر محلی از فایل‌های میزبان.
  • container_path: مسیری است که در داخل کانتینر داده‌ها باید نگهداری شوند.

انواع مختلف volumes:

1. استفاده از Volume های Docker (Volume های نام‌گذاری شده)

در این روش، Docker خودش یک فضای ذخیره‌سازی مخصوص به نام "volume" ایجاد می‌کند که به طور خودکار مدیریت می‌شود و داده‌ها را در خود ذخیره می‌کند.

version: '3.8'

services:
  app:
    image: my-app
    volumes:
      - my-volume:/data

در اینجا:

  • my-volume:/data به این معنی است که Docker یک volume به نام my-volume ایجاد می‌کند و آن را به مسیر /data در داخل کانتینر متصل می‌کند.
  • این volume در جایی خارج از کانتینر ذخیره می‌شود و داده‌ها در آن حفظ می‌شوند.

2. استفاده از مسیرهای محلی (bind mounts)

در این حالت، شما یک مسیر خاص از ماشین میزبان را به مسیر داخل کانتینر متصل می‌کنید. این روش معمولاً برای اشتراک‌گذاری داده‌ها بین میزبان و کانتینر (مثل فایل‌های کد پروژه) استفاده می‌شود.

version: '3.8'

services:
  app:
    image: my-app
    volumes:
      - ./local-folder:/app

در اینجا:

  • ./local-folder:/app به این معنی است که پوشه local-folder که در دایرکتوری فعلی میزبان قرار دارد، به مسیر /app داخل کانتینر متصل می‌شود.
  • هر تغییری که در local-folder ایجاد شود، به طور مستقیم در کانتینر هم اعمال خواهد شد.

3. استفاده از Volume های مشخص (Named Volumes)

در صورتی که بخواهید یک volume خاص برای ذخیره داده‌ها ایجاد کنید، می‌توانید از volumes نام‌گذاری شده استفاده کنید. این volumes به صورت خودکار توسط Docker مدیریت می‌شوند و در مکان‌هایی ذخیره می‌شوند که Docker به طور پیش‌فرض استفاده می‌کند.

version: '3.8'

services:
  app:
    image: my-app
    volumes:
      - app_data:/var/lib/my-app/data

volumes:
  app_data:

در اینجا:

  • app_data:/var/lib/my-app/data: یک volume به نام app_data ایجاد می‌شود که داده‌ها را در مسیر /var/lib/my-app/data داخل کانتینر ذخیره می‌کند.
  • در اینجا، بخش volumes در سطح بالاتر از کانتینر تعریف شده و Docker به طور خودکار یک volume به نام app_data ایجاد می‌کند.

4. استفاده از Volumes برای چندین کانتینر

ممکن است بخواهید از یک volume برای اشتراک‌گذاری داده‌ها بین چندین کانتینر استفاده کنید. این کار می‌تواند برای کاربردهایی مثل اشتراک‌گذاری داده‌ها بین چندین سرویس یا کانتینر مفید باشد.

version: '3.8'

services:
  web:
    image: nginx
    volumes:
      - shared-data:/usr/share/nginx/html

  app:
    image: my-app
    volumes:
      - shared-data:/app/data

volumes:
  shared-data:

در اینجا:

  • کانتینر web و app هر دو از volume به نام shared-data استفاده می‌کنند.
  • این volume داده‌ها را بین این دو کانتینر به اشتراک می‌گذارد، به‌طوری‌که هر دو کانتینر به داده‌های یکسان دسترسی خواهند داشت.

ویژگی‌ها و مزایای استفاده از volumes:

  1. حفظ داده‌ها پس از حذف کانتینرها: اگر کانتینری را حذف کنید، داده‌ها در volumes باقی خواهند ماند و می‌توانید آنها را در کانتینرهای جدید یا دیگر سرویس‌ها استفاده کنید.

  2. اشتراک‌گذاری داده‌ها بین کانتینرها: اگر چندین کانتینر به یک volume مشترک دسترسی داشته باشند، می‌توانند داده‌ها را به راحتی به اشتراک بگذارند.

  3. مدیریت بهتر داده‌ها: با استفاده از volumes، شما می‌توانید داده‌ها را به صورت ایمن و سازمان‌یافته ذخیره کنید، و Docker مسئولیت نگهداری و مدیریت حجم ذخیره‌سازی را بر عهده می‌گیرد.

  4. مناسب برای پایگاه داده‌ها و فایل‌های دائم: زمانی که از پایگاه داده‌ها یا داده‌های دائم استفاده می‌کنید (مثل فایل‌های آپلود شده یا اطلاعات حساس)، استفاده از volume به شما کمک می‌کند تا از دست رفتن داده‌ها در صورت توقف یا حذف کانتینر جلوگیری کنید.

  5. سازگاری بین سیستم‌ها: استفاده از volumes باعث می‌شود که داده‌ها به راحتی بین محیط‌های مختلف (مثل توسعه، تست، و تولید) به اشتراک گذاشته شوند، زیرا داده‌ها از کانتینرها جدا هستند و می‌توانند به طور مستقل از سیستم‌ها یا نسخه‌های Docker اجرا شوند.

نتیجه‌گیری:

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


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

depends_on

services:
  <service1_name>:
    image: <image_name>

  <service2_name>:
    image: <image_name>
    depends_on:
      - <service1_name>

در اینجا:

  • <service2_name> به <service1_name> وابسته است و Docker Compose باید ابتدا <service1_name> را راه‌اندازی کند قبل از اینکه <service2_name> راه‌اندازی شود.

جزئیات استفاده از depends_on:

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

فرض کنید دو سرویس دارید، یکی برای وب‌سایت (مانند یک سرویس Nginx) و دیگری برای پایگاه داده (مانند MySQL). اگر سرویس وب‌سایت نیاز به پایگاه داده داشته باشد، می‌توانید از depends_on برای اطمینان از این که پایگاه داده ابتدا راه‌اندازی شده است استفاده کنید.

version: '3.8'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example

  web:
    image: nginx
    depends_on:
      - db

در اینجا:

  • web (Nginx) به db (MySQL) وابسته است و Docker Compose مطمئن می‌شود که سرویس db قبل از web راه‌اندازی شود.

2. تعیین ترتیب راه‌اندازی کانتینرها

استفاده از depends_on فقط ترتیب راه‌اندازی کانتینرها را مدیریت می‌کند. به این معنی که این گزینه فقط اطمینان می‌دهد که کانتینرهایی که وابسته به یکدیگر هستند در یک ترتیب خاص راه‌اندازی شوند، اما هیچ تضمینی برای آماده بودن سرویس‌ها برای برقراری ارتباط یا استفاده از سرویس‌های دیگر ندارد.

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

3. راه‌حل برای اطمینان از آماده بودن سرویس‌ها

در صورتی که شما بخواهید اطمینان حاصل کنید که یک سرویس به طور کامل راه‌اندازی شده و آماده است قبل از اینکه سرویس دیگری شروع به کار کند (برای مثال پایگاه داده آماده باشد تا وب‌سایت بتواند به آن متصل شود)، می‌توانید از روش‌های دیگری مانند healthcheck یا wait-for-it استفاده کنید.

مثال استفاده از healthcheck:

version: '3.8'

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      retries: 5
      start_period: 5s
      timeout: 5s

  web:
    image: nginx
    depends_on:
      - db

در اینجا:

  • healthcheck به Docker این امکان را می‌دهد که بررسی کند آیا سرویس db به طور کامل راه‌اندازی و آماده است.
  • با این حال، در این مثال، Docker Compose هنوز هم ابتدا سرویس db را راه‌اندازی می‌کند، ولی باید از متدهای دیگری برای مدیریت صحت و آماده بودن سرویس‌ها استفاده کنید.

4. محدودیت‌ها و نکات مربوط به depends_on

  • depends_on فقط ترتیب راه‌اندازی کانتینرها را مدیریت می‌کند و هیچ کنترلی روی وضعیت "آماده بودن" سرویس‌ها ندارد.
  • برای بررسی وضعیت سرویس‌ها و اطمینان از آماده بودن آن‌ها، باید از healthcheck استفاده کنید.
  • در برخی از نسخه‌های Docker Compose، depends_on فقط ترتیبی برای راه‌اندازی سرویس‌ها ایجاد می‌کند و اگر یک سرویس دارای مشکلات باشد (مثلاً یک سرویس پایگاه داده هنوز راه‌اندازی نشده)، به طور خودکار نمی‌تواند تأخیر ایجاد کند. برای کنترل دقیق‌تر، باید از ابزارهایی مانند wait-for-it یا dockerize برای بررسی وضعیت سرویس‌ها استفاده کنید.

نتیجه‌گیری:

گزینه depends_on در Docker Compose برای تعیین وابستگی‌ها و ترتیب راه‌اندازی سرویس‌ها استفاده می‌شود، ولی باید به این نکته توجه داشته باشید که depends_on تنها ترتیب راه‌اندازی را مشخص می‌کند و نمی‌تواند تضمین کند که یک سرویس کاملاً آماده برای استفاده است. برای مدیریت وضعیت و آماده بودن سرویس‌ها، می‌توانید از ویژگی healthcheck یا ابزارهای دیگری مانند wait-for-it استفاده کنید.


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

restart

  1. no (پیش‌فرض)
  2. always
  3. unless-stopped
  4. on-failure

توضیحات کامل در مورد هر یک از این مقادیر:

1. no (پیش‌فرض)

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

نمونه استفاده:

services:
  app:
    image: my-app
    restart: "no"

در این حالت:

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

2. always

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

نمونه استفاده:

services:
  app:
    image: my-app
    restart: "always"

در این حالت:

  • اگر کانتینر app متوقف شود، Docker آن را بلافاصله دوباره راه‌اندازی خواهد کرد.
  • حتی اگر کانتینر دستی متوقف شود (با دستور docker stop)، باز هم Docker آن را دوباره راه‌اندازی می‌کند.
  • این گزینه معمولاً برای سرویس‌هایی که باید همیشه در حال اجرا باشند (مثل دیتابیس‌ها یا وب‌سایت‌های در حال خدمت) استفاده می‌شود.

3. unless-stopped

این گزینه مشابه always است، با این تفاوت که اگر کانتینر به صورت دستی متوقف شود (با دستور docker stop)، Docker دیگر آن را دوباره راه‌اندازی نخواهد کرد. این گزینه مفید است وقتی که شما می‌خواهید کانتینر همیشه در حال اجرا باشد، مگر اینکه خودتان به طور دستی آن را متوقف کنید.

نمونه استفاده:

services:
  app:
    image: my-app
    restart: "unless-stopped"

در این حالت:

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

4. on-failure

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

نمونه استفاده:

services:
  app:
    image: my-app
    restart: "on-failure"

در این حالت:

  • اگر کانتینر app به دلیل خطا متوقف شود (مثلاً کد برنامه شما خطا دهد)، Docker تلاش خواهد کرد که آن را دوباره راه‌اندازی کند.
  • در صورتی که کانتینر به صورت عادی (بدون خطا) متوقف شود، Docker آن را دوباره راه‌اندازی نمی‌کند.
  • شما می‌توانید حتی تعداد دفعات تلاش برای راه‌اندازی مجدد کانتینر را تعیین کنید. مثلاً می‌توانید بگویید که اگر کانتینر بیشتر از 5 بار خطا داد، دیگر راه‌اندازی مجدد نشود.

نمونه استفاده با تعداد دفعات مشخص:

services:
  app:
    image: my-app
    restart: "on-failure:5"

در این حالت:

  • اگر کانتینر app بیشتر از 5 بار متوقف شود به دلیل خطا، Docker دیگر تلاش نمی‌کند آن را راه‌اندازی کند.

نتیجه‌گیری:

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


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

۱. شبکه‌های Docker

Docker به طور پیش‌فرض چندین نوع شبکه مختلف را برای برقراری ارتباط بین کانتینرها ارائه می‌دهد. برخی از این شبکه‌ها عبارتند از:

  1. bridge
  2. host
  3. none
  4. overlay

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

۲. شبکه‌ها در Docker Compose

ساختار استفاده از networks در Compose:

در فایل Docker Compose، شبکه‌ها را می‌توان در سطح services و networks تنظیم کرد.

version: '3.8'

services:
  app:
    image: my-app
    networks:
      - app-network

  db:
    image: mysql
    networks:
      - app-network
    environment:
      MYSQL_ROOT_PASSWORD: example

networks:
  app-network:
    driver: bridge

در اینجا:

  • دو سرویس app و db به شبکه‌ای به نام app-network متصل می‌شوند.
  • در قسمت networks تعریف می‌شود که از driver برای این شبکه استفاده شود (در اینجا bridge).

۳. انواع شبکه‌ها در Docker

Docker انواع مختلفی از شبکه‌ها را برای استفاده در Compose ارائه می‌دهد. در اینجا به شرح هر یک از آنها می‌پردازیم:

۳.۱. شبکه bridge

شبکه bridge پیش‌فرض Docker است و برای بیشتر موارد استفاده می‌شود. در این شبکه، کانتینرها می‌توانند با یکدیگر ارتباط برقرار کنند، اما از شبکه میزبان خود (host network) جدا هستند.

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

نمونه استفاده از شبکه bridge:

version: '3.8'

services:
  app:
    image: my-app
    networks:
      - app-network

  db:
    image: mysql
    networks:
      - app-network
    environment:
      MYSQL_ROOT_PASSWORD: example

networks:
  app-network:
    driver: bridge

۳.۲. شبکه host

در شبکه host، کانتینرها به طور مستقیم از شبکه میزبان استفاده می‌کنند. این یعنی که کانتینرها از همان IP و پورت‌هایی که میزبان از آن استفاده می‌کند، بهره‌مند خواهند بود.

  • زمانی استفاده می‌شود که شما بخواهید عملکرد کانتینر مشابه سیستم میزبان باشد (مثلاً برای استفاده از شبکه‌های پرسرعت).
  • ویژگی‌ها:
    • هیچ جدا سازی شبکه‌ای بین کانتینرها و میزبان وجود ندارد.
    • اگر کانتینر دارای آدرس IP خاصی باشد، میزبان همان آدرس IP را دارد.

نمونه استفاده از شبکه host:

version: '3.8'

services:
  app:
    image: my-app
    networks:
      - host
    network_mode: "host"

networks:
  host:
    driver: host

۳.۳. شبکه none

در شبکه none، کانتینر به هیچ شبکه‌ای متصل نمی‌شود. این انتخاب برای زمانی است که شما نمی‌خواهید هیچ ارتباط شبکه‌ای برای کانتینر فراهم کنید.

  • زمانی استفاده می‌شود که نیاز به یک کانتینر ایزوله دارید که هیچ ارتباطی با دیگر کانتینرها یا سیستم خارجی نداشته باشد.
  • ویژگی‌ها:
    • کانتینر هیچ IP یا شبکه‌ای ندارد.
    • برای تست یا ایزوله کردن سرویس‌ها استفاده می‌شود.

نمونه استفاده از شبکه none:

version: '3.8'

services:
  app:
    image: my-app
    networks:
      - none
    network_mode: "none"

networks:
  none:
    driver: null

۳.۴. شبکه overlay

شبکه overlay بیشتر در محیط‌های Docker Swarm یا Kubernetes استفاده می‌شود. این شبکه به شما این امکان را می‌دهد که کانتینرهای موجود در میزبان‌های مختلف را به یکدیگر متصل کنید.

  • زمانی استفاده می‌شود که شما می‌خواهید سرویس‌ها را در چندین میزبان Docker (در یک خوشه) اجرا کنید.
  • ویژگی‌ها:
    • کانتینرها در میزبان‌های مختلف می‌توانند با یکدیگر ارتباط برقرار کنند.
    • این شبکه برای کاربردهایی که به مقیاس‌پذیری نیاز دارند (مانند Docker Swarm) مناسب است.

نمونه استفاده از شبکه overlay:

version: '3.8'

services:
  app:
    image: my-app
    networks:
      - my_overlay_network

  db:
    image: mysql
    networks:
      - my_overlay_network

networks:
  my_overlay_network:
    driver: overlay
    attachable: true

۴. چگونه شبکه‌ها را در Docker Compose تعریف کنیم؟

۴.۱. شبکه‌های پیش‌فرض

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

۴.۲. تعریف شبکه‌ها در بخش networks

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

۵. ویژگی‌های شبکه‌ها در Docker Compose

  • driver: تعیین می‌کند که از کدام نوع شبکه استفاده شود (مثلاً bridge، host، overlay).
  • driver_opts: این گزینه به شما اجازه می‌دهد تنظیمات اضافی برای درایور شبکه‌ها مشخص کنید.
  • internal: این ویژگی به شما این امکان را می‌دهد که شبکه‌ای داخلی بسازید که خارج از دسترس اینترنت یا سایر شبکه‌ها باشد.
  • attachable: این ویژگی به شما این امکان را می‌دهد که کانتینرها به شبکه‌ای که برای Docker Swarm ایجاد کرده‌اید متصل شوند.

نمونه استفاده از driver_opts و ویژگی‌های دیگر:

version: '3.8'

services:
  web:
    image: nginx
    networks:
      mynetwork:
        aliases:
          - web.local

networks:
  mynetwork:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: mybridge
    internal: true

در اینجا:

  • شبکه mynetwork از نوع bridge است.
  • driver_opts برای تنظیمات اضافی به کار می‌رود.
  • internal به این معناست که این شبکه فقط برای ارتباط داخلی است و از شبکه‌های خارجی قابل دسترسی نخواهد بود.

نتیجه‌گیری:

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


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

healthcheck

  1. بررسی سلامت سرویس‌ها:

    • به شما این امکان را می‌دهد که از طریق دستورات خاصی وضعیت سلامت سرویس‌های داخل کانتینر را بررسی کنید. مثلاً، بررسی کنید که پایگاه داده به درستی کار می‌کند یا وب‌سایت به درستی بارگذاری می‌شود.
  2. توقف یا راه‌اندازی مجدد کانتینرها:

    • اگر کانتینر سلامتی خود را از دست دهد (مثلاً به دلایل مختلف مانند خطاهای برنامه یا عدم اتصال به پایگاه داده)، Docker می‌تواند به طور خودکار کانتینر را دوباره راه‌اندازی کند.

نحوه استفاده از healthcheck:

در زیر نمونه‌ای از نحوه تنظیم healthcheck برای یک کانتینر در Docker Compose آورده شده است:

version: '3.8'

services:
  app:
    image: my-app
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      retries: 3
      start_period: 10s
      timeout: 5s

توضیح گزینه‌های healthcheck:

  • test:

    • این قسمت برای مشخص کردن دستوری است که باید برای بررسی سلامت کانتینر اجرا شود. در این مثال، از دستور curl برای ارسال درخواست به آدرس http://localhost:8080/health استفاده می‌شود تا وضعیت سلامت سرویس را بررسی کند.
    • می‌توانید از دستورات مختلف برای بررسی وضعیت سرویس‌ها استفاده کنید (مثلاً CMD برای اجرای دستور و CMD-SHELL برای اجرای دستورات شل).
  • interval:

    • فاصله زمانی بین هر بار اجرای دستور تست سلامت را مشخص می‌کند. در این مثال، دستور تست هر 30 ثانیه یکبار اجرا می‌شود.
  • retries:

    • تعداد دفعاتی که Docker باید تلاش کند تا دستور test با موفقیت اجرا شود. اگر تعداد دفعات شکست از مقدار مشخص شده بیشتر باشد، کانتینر به عنوان "غیراقتصادی" شناخته می‌شود.
  • start_period:

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

    • حداکثر زمانی که برای اجرای دستور test تعیین می‌شود. اگر دستور تست بعد از این مدت زمان کامل نشود، به عنوان شکست در نظر گرفته می‌شود.

مثال‌های مختلف از healthcheck:

1. استفاده از دستور curl برای بررسی API سلامت

در این مثال، از curl برای بررسی سلامت یک سرویس وب (API) استفاده می‌شود.

services:
  web:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 20s
      retries: 3
      start_period: 10s
      timeout: 5s

در اینجا:

  • دستور curl -f http://localhost/health بررسی می‌کند که آیا API سلامت پاسخ می‌دهد یا خیر.
  • اگر سه بار تلاش برای بررسی وضعیت سلامت شکست بخورد، کانتینر به عنوان خراب شناخته می‌شود.

2. استفاده از دستور mysqladmin برای بررسی سلامت پایگاه داده

اگر کانتینر شما شامل یک سرویس پایگاه داده (مثل MySQL) باشد، می‌توانید از دستور mysqladmin ping برای بررسی سلامت پایگاه داده استفاده کنید.

services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 30s
      retries: 5
      start_period: 10s
      timeout: 5s

در اینجا:

  • دستور mysqladmin ping بررسی می‌کند که آیا پایگاه داده به درستی در حال کار است.
  • اگر پایگاه داده در دسترس نباشد، Docker در تلاش‌های بعدی آن را دوباره بررسی می‌کند.

3. استفاده از دستورات CMD-SHELL برای اجرای چندین دستور

در صورتی که نیاز به اجرای چندین دستور به طور همزمان برای بررسی سلامت کانتینر داشته باشید، می‌توانید از CMD-SHELL استفاده کنید.

services:
  app:
    image: my-app
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
      interval: 20s
      retries: 3
      start_period: 10s
      timeout: 5s

در اینجا:

  • از CMD-SHELL استفاده می‌شود تا دستور curl را اجرا کند و اگر وضعیت سلامت مناسب نباشد، به exit 1 برسد تا نشان دهد که کانتینر خراب است.

نتیجه‌گیری:

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


در Docker Compose، گزینه‌های cpu و mem برای محدود کردن منابع سیستم (مثل CPU و حافظه) که یک سرویس می‌تواند استفاده کند، به کار می‌روند. این ویژگی به شما این امکان را می‌دهد که میزان منابع سیستم را برای هر کانتینر مشخص کنید و از استفاده بیش از حد منابع جلوگیری کنید.

1. محدود کردن استفاده از CPU (cpu)

1.1. cpu در Docker Compose

برای محدود کردن استفاده از CPU در Docker Compose، می‌توانید از گزینه‌های مختلفی استفاده کنید. این محدودیت‌ها به شما این امکان را می‌دهند که از بار اضافی روی سیستم جلوگیری کنید و کارایی کانتینرها را بهینه کنید.

ویژگی‌های مرتبط با CPU در Docker:

  1. cpu_shares:

    • این گزینه میزان سهمی که یک کانتینر از CPU را دریافت می‌کند مشخص می‌کند. این مقدار به صورت عددی بیان می‌شود که به کانتینر اولویت می‌دهد. به طور پیش‌فرض، این مقدار برابر با 1024 است.
  2. cpu_quota:

    • این گزینه برای محدود کردن استفاده از CPU به یک مقدار خاص استفاده می‌شود. اگر می‌خواهید استفاده از CPU را محدود کنید، می‌توانید از این گزینه استفاده کنید.
  3. cpu_period:

    • این گزینه در کنار cpu_quota استفاده می‌شود. در واقع مدت زمانی که CPU به یک کانتینر اختصاص می‌یابد را مشخص می‌کند.
  4. cpus:

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

مثال محدود کردن CPU در Docker Compose:

version: '3.8'

services:
  app:
    image: my-app
    deploy:
      resources:
        limits:
          cpus: '0.5'  # محدود کردن به نصف یک هسته CPU
        reservations:
          cpus: '0.25'  # رزرو یک چهارم هسته CPU

در این مثال:

  • cpus: '0.5' به این معنی است که کانتینر app می‌تواند فقط از نیم هسته CPU استفاده کند.
  • reservations برای رزرو منابع در نظر گرفته شده است، به طوری که سیستم تضمین می‌کند که حداقل 0.25 هسته CPU برای کانتینر در دسترس باشد.

2. محدود کردن استفاده از حافظه (mem)

2.1. mem در Docker Compose

برای محدود کردن استفاده از حافظه (RAM) در Docker Compose، می‌توانید از گزینه‌های مختلفی استفاده کنید که مشابه محدودیت‌های CPU عمل می‌کنند.

ویژگی‌های مرتبط با حافظه در Docker:

  1. mem_limit:

    • این گزینه برای محدود کردن میزان حافظه‌ای که یک کانتینر می‌تواند استفاده کند به کار می‌رود. می‌توانید این مقدار را به صورت MB یا GB مشخص کنید.
  2. mem_reservation:

    • این گزینه میزان حافظه‌ای است که به طور موقت برای کانتینر رزرو می‌شود. این بدان معناست که اگر سیستم نیاز به منابع اضافی داشت، سیستم آن منابع را از کانتینرهایی که دارای mem_reservation هستند می‌گیرد.
  3. memswap_limit:

    • این گزینه به شما این امکان را می‌دهد که میزان حافظه swap را برای کانتینر تنظیم کنید.

مثال محدود کردن حافظه در Docker Compose:

version: '3.8'

services:
  app:
    image: my-app
    deploy:
      resources:
        limits:
          memory: 500M  # محدود کردن حافظه به 500MB
        reservations:
          memory: 200M  # رزرو 200MB حافظه

در این مثال:

  • memory: 500M به این معنی است که کانتینر app می‌تواند تنها 500MB حافظه استفاده کند. اگر بیشتر از این مقدار بخواهد استفاده کند، یا متوقف می‌شود یا شروع به استفاده از swap خواهد کرد.
  • reservations به این معنی است که حداقل 200MB حافظه برای این کانتینر رزرو شده است.

3. محدودیت‌ها و ویژگی‌ها در Docker Compose

  • limits: برای تعیین بیشترین مقدار منابع استفاده‌شده (مانند حداکثر CPU یا حافظه).
  • reservations: برای رزرو منابع خاص به صورت حداقل در نظر گرفته می‌شود.

4. مزایای استفاده از محدودیت‌ها

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

نتیجه‌گیری:

استفاده از cpu و mem در Docker Compose به شما این امکان را می‌دهد که منابع سیستمی را برای هر سرویس محدود کنید. این ویژگی می‌تواند به شما کمک کند تا از استفاده بیش از حد منابع جلوگیری کنید، عملکرد سیستم را بهینه کنید، و ایزوله‌سازی بهتری بین کانتینرها ایجاد کنید. همچنین با استفاده از cpu_shares، cpu_quota، memory و سایر گزینه‌ها، شما می‌توانید کنترل دقیقی روی نحوه تخصیص منابع داشته باشید.


در Docker Compose، گزینه labels به شما این امکان را می‌دهد که برچسب‌هایی به کانتینرها و سرویس‌ها اضافه کنید. این برچسب‌ها (Labels) به عنوان اطلاعات متا برای مدیریت، سازماندهی، و نظارت بر کانتینرها و سرویس‌ها مورد استفاده قرار می‌گیرند. برچسب‌ها می‌توانند برای شناسایی، جستجو، و فیلتر کردن کانتینرها و سرویس‌ها در سیستم‌های بزرگتر مفید باشند.

کاربردهای labels:

  1. مدیریت و شناسایی بهتر: برچسب‌ها می‌توانند به شما کمک کنند که سرویس‌ها یا کانتینرها را بهتر شناسایی و مدیریت کنید. به عنوان مثال، می‌توانید از برچسب‌ها برای مشخص کردن نسخه‌های مختلف نرم‌افزار یا محیط‌های مختلف (توسعه، تست، تولید) استفاده کنید.

  2. نظارت و ابزارهای جانبی: ابزارهای نظارت و مدیریت، مانند Prometheus یا Docker Swarm، می‌توانند از برچسب‌ها برای جلب توجه به مسائل خاص یا اجرای سیاست‌های خاص استفاده کنند.

  3. جستجو و فیلتر کردن کانتینرها: برچسب‌ها می‌توانند به شما این امکان را بدهند که کانتینرها را بر اساس ویژگی‌های خاص یا نیازهای مدیریتی فیلتر کنید.

نحوه استفاده از labels در Docker Compose:

شما می‌توانید برچسب‌ها را در بخش‌های مختلف فایل Compose اضافه کنید. معمولاً از این ویژگی در بخش سرویس‌ها برای افزودن اطلاعات متا به کانتینر استفاده می‌شود.

مثال استفاده از labels در Docker Compose:

version: '3.8'

services:
  web:
    image: nginx
    labels:
      - "env=production"
      - "version=1.0.0"
      - "tier=frontend"
  app:
    image: my-app
    labels:
      - "env=development"
      - "version=2.1.0"
      - "tier=backend"

توضیح برچسب‌ها:

  • env=production و env=development: این برچسب‌ها نشان‌دهنده محیط‌های مختلف هستند. این می‌تواند به شما کمک کند که کانتینرهایی که در محیط‌های تولیدی یا توسعه‌ای هستند را به راحتی شناسایی کنید.

  • version=1.0.0 و version=2.1.0: برچسب‌های نسخه می‌توانند به شما کمک کنند تا نسخه‌های مختلف برنامه‌های خود را شناسایی کنید. این ویژگی برای مدیریت نسخه‌ها و اطمینان از استفاده از نسخه‌های صحیح کاربردی است.

  • tier=frontend و tier=backend: این برچسب‌ها نشان‌دهنده بخش یا لایه‌های مختلف سیستم شما هستند. در این مثال، یک کانتینر برای قسمت frontend و دیگری برای قسمت backend سرویس‌ها است.

مزایای استفاده از labels:

  1. مدیریت بهتر در محیط‌های بزرگ: با افزودن برچسب‌های معنادار، می‌توانید کانتینرها و سرویس‌ها را به راحتی مدیریت کنید.

  2. امکان فیلتر کردن و جستجو: ابزارهای مدیریت و نظارت می‌توانند از برچسب‌ها برای فیلتر کردن سرویس‌ها و کانتینرها بر اساس ویژگی‌های خاص استفاده کنند.

  3. اطلاعات متا: برچسب‌ها می‌توانند به عنوان اطلاعات اضافی برای شناسایی ویژگی‌ها، نسخه‌ها، یا حتی کاربردهای خاص یک کانتینر یا سرویس استفاده شوند.

نکات:

  • برچسب‌ها به صورت key=value تعریف می‌شوند.
  • برچسب‌ها می‌توانند برای اهداف مختلف مانند نظارت، مدیریت، شناسایی، یا گزارش‌دهی به کار روند.
  • این ویژگی می‌تواند در کنار سایر ویژگی‌های Docker مانند docker ps یا ابزارهای مدیریتی مانند Docker Swarm یا Kubernetes برای اعمال سیاست‌ها و جستجوهای خاص به کار رود.

نتیجه‌گیری:

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


در Docker Compose، گزینه extra_hosts برای اضافه کردن ورودی‌های سفارشی به فایل /etc/hosts کانتینر استفاده می‌شود. این ویژگی به شما این امکان را می‌دهد که آدرس‌های IP و نام‌های دامنه را به صورت دستی به فایل /etc/hosts کانتینر اضافه کنید، که معمولاً برای تنظیمات خاص شبکه یا دسترسی به سرویس‌ها از طریق نام‌های دامنه سفارشی مفید است.

extra_hosts

  1. تنظیمات شبکه خاص: با استفاده از extra_hosts می‌توانید نام‌های دامنه سفارشی یا آدرس‌های IP خاص را به کانتینر اضافه کنید تا به سرویس‌ها و سیستم‌ها در شبکه‌های مختلف دسترسی پیدا کنید.

  2. حل مشکلات DNS: زمانی که Docker DNS به طور پیش‌فرض به درستی کار نمی‌کند یا شما نیاز به اتصال به سیستم‌هایی دارید که در شبکه‌های خارجی هستند، می‌توانید از extra_hosts برای افزودن ورودی‌های مورد نیاز به فایل /etc/hosts کانتینر استفاده کنید.

  3. اتصال به سرویس‌های دیگر: گاهی اوقات ممکن است نیاز داشته باشید که یک کانتینر به سرویس‌هایی خارج از Docker دسترسی داشته باشد، یا حتی به سرویس‌های دیگری که در یک شبکه خاص داخل Docker قرار دارند، وصل شود. با استفاده از extra_hosts می‌توانید این ارتباطات را برقرار کنید.

نحوه استفاده از extra_hosts:

برای استفاده از extra_hosts، باید در فایل Docker Compose آن را در زیرمجموعه سرویس مورد نظر اضافه کنید. این ویژگی به شما این امکان را می‌دهد که ورودی‌های خاصی را به فایل /etc/hosts کانتینر اضافه کنید. هر ورودی به صورت hostname:ip تعیین می‌شود.

مثال استفاده از extra_hosts در Docker Compose:

version: '3.8'

services:
  web:
    image: nginx
    extra_hosts:
      - "example.com:192.168.1.100"
      - "api.local:10.0.0.5"

در این مثال:

  • برای سرویس web که از nginx استفاده می‌کند، دو ورودی به /etc/hosts کانتینر اضافه می‌شود.
    • ورودی example.com:192.168.1.100 به این معنی است که در کانتینر، example.com به 192.168.1.100 اشاره می‌کند.
    • ورودی api.local:10.0.0.5 به این معنی است که در کانتینر، api.local به 10.0.0.5 اشاره می‌کند.

توضیح بخش‌های مختلف extra_hosts:

  • hostname: نام دامنه یا هاست که می‌خواهید به کانتینر اضافه کنید.
  • ip_address: آدرس IP که می‌خواهید به آن نام دامنه یا هاست اختصاص دهید.

مزایای استفاده از extra_hosts:

  1. شبکه‌های پیچیده: زمانی که کانتینرهای شما نیاز دارند به سرویس‌هایی خارج از Docker یا سرویس‌هایی در شبکه‌های مختلف دسترسی پیدا کنند، می‌توانید از extra_hosts برای اتصال به آن‌ها استفاده کنید.
  2. حل مشکلات DNS داخلی: گاهی اوقات ممکن است سیستم‌های DNS داخلی به درستی کار نکنند یا نیاز به تنظیمات خاصی برای اتصال به سرویس‌ها داشته باشید. در این صورت، اضافه کردن آدرس‌های IP به فایل /etc/hosts می‌تواند کمک‌کننده باشد.
  3. سفارشی‌سازی فایل /etc/hosts کانتینر: می‌توانید فایل /etc/hosts هر کانتینر را مطابق با نیاز خود تغییر دهید بدون نیاز به دستکاری دستی فایل در داخل کانتینر.

نکات:

  • extra_hosts فقط ورودی‌ها را به فایل /etc/hosts اضافه می‌کند. اگر کانتینر از DNS برای اتصال به هاست‌ها استفاده می‌کند، این ویژگی به آن تغییری نمی‌دهد.
  • برچسب‌های extra_hosts معمولاً برای مدیریت شبکه‌های پیچیده یا اتصال به سرویس‌هایی استفاده می‌شود که به طور پیش‌فرض از نام‌های DNS داخلی Docker قابل دسترسی نیستند.

نتیجه‌گیری:

استفاده از extra_hosts در Docker Compose یک روش مفید برای اضافه کردن ورودی‌های سفارشی به فایل /etc/hosts کانتینرها است. این ویژگی به شما کمک می‌کند تا شبکه‌های پیچیده را مدیریت کنید و به سرویس‌ها و سیستم‌های خاص از طریق نام‌های دامنه دلخواه دسترسی پیدا کنید. user توضیح بده ChatGPT در Docker Compose، گزینه user به شما این امکان را می‌دهد که مشخص کنید که کانتینر تحت کدام کاربر و گروه اجرا شود. این ویژگی برای مسائل امنیتی و مدیریت دسترسی‌ها مفید است، زیرا می‌توانید مشخص کنید که کانتینر با چه مجوزهایی (permissions) اجرا شود.

کاربردهای user:

  1. امنیت بیشتر: به طور پیش‌فرض، کانتینرها با کاربر root اجرا می‌شوند، که این ممکن است به دلیل مجوزهای بالای دسترسی که به آن داده می‌شود، مشکلات امنیتی به همراه داشته باشد. با استفاده از گزینه user می‌توانید کانتینر را تحت یک کاربر خاص اجرا کنید که دسترسی‌های محدودی دارد.

  2. اجرا با دسترسی‌های محدودتر: استفاده از user به شما این امکان را می‌دهد که کانتینرها را تحت یک کاربر خاص با دسترسی‌های محدود اجرا کنید تا در صورت بروز حمله یا نفوذ، آسیب‌های احتمالی به سیستم میزبان (host) کاهش یابد.

  3. اجرای کانتینر با دسترسی‌های مشابه میزبان: گاهی اوقات ممکن است بخواهید کانتینر با همان کاربر و گروهی که در سیستم میزبان (host) وجود دارد، اجرا شود تا دسترسی‌ها و مجوزها به درستی تنظیم شوند. این کار می‌تواند به خصوص زمانی مفید باشد که نیاز به دسترسی به فایل‌ها یا دایرکتوری‌های خاص میزبان از داخل کانتینر دارید.

نحوه استفاده از user در Docker Compose:

مقدار user می‌تواند به صورت UID:GID (شناسه کاربر و شناسه گروه) یا به صورت نام کاربری و گروه باشد.

انواع استفاده از user:

  1. با استفاده از UID و GID:

    • UID شناسه عددی کاربر (User ID) است و GID شناسه عددی گروه (Group ID) است.

    مثال:

    version: '3.8'
    services:
      app:
        image: my-app
        user: "1001:1001"  # اجرا با UID و GID خاص
    

    در این مثال، کانتینر تحت کاربری با UID 1001 و گروه با GID 1001 اجرا می‌شود.

  2. با استفاده از نام کاربر و گروه:

    • می‌توانید نام کاربر و گروه را به صورت متنی نیز وارد کنید.

    مثال:

    version: '3.8'
    services:
      app:
        image: my-app
        user: "username:groupname"  # اجرا با نام کاربر و گروه
    

    در اینجا، کانتینر تحت کاربر و گروه خاص اجرا می‌شود.

  3. اجرا به صورت root (کاربر پیش‌فرض):

    • اگر گزینه user را نادیده بگیرید یا تنظیم نکنید، کانتینر به طور پیش‌فرض تحت کاربر root اجرا خواهد شد. اما معمولاً بهتر است که از این روش خودداری کنید، مگر در مواقع خاص که نیاز به دسترسی ریشه (root) دارید.

مزایای استفاده از user:

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

نکات:

  • استفاده از user برای جلوگیری از اجرای کانتینر به عنوان root به شدت توصیه می‌شود.
  • در برخی از موارد، لازم است که در فایل‌های کانتینر یا تنظیمات دیگر، دسترسی‌های کاربر و گروه را هماهنگ کنید تا اطمینان حاصل کنید که کانتینر به درستی کار می‌کند.
  • در صورتی که کانتینر شما به منابع خاصی نیاز دارد که به یک کاربر خاص محدود شده‌اند، می‌توانید با تنظیم user به این منابع دسترسی پیدا کنید.

نتیجه‌گیری:

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


در Docker Compose، گزینه ulimits به شما این امکان را می‌دهد که محدودیت‌هایی برای منابع سیستم مانند تعداد فایل‌های باز، پردازش‌ها و دیگر منابع سیستم اعمال کنید. این ویژگی به خصوص برای مدیریت منابع در کانتینرها و جلوگیری از مصرف بیش از حد منابع سیستم میزبان (host) بسیار مفید است.

ulimits

  1. محدود کردن تعداد فایل‌های باز: کانتینرها ممکن است تعداد زیادی فایل باز کنند. اگر این تعداد بیش از حد باشد، ممکن است سیستم میزبان دچار مشکلاتی مانند پر شدن جدول فایل‌ها شود. با استفاده از ulimits می‌توانید این تعداد را محدود کنید.

  2. محدود کردن تعداد پردازش‌ها: برای جلوگیری از ایجاد بار اضافی در سیستم، می‌توانید محدودیت‌هایی برای تعداد پردازش‌هایی که یک کانتینر می‌تواند اجرا کند، تنظیم کنید.

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

انواع محدودیت‌هایی که می‌توانید تنظیم کنید:

در بخش ulimits، شما می‌توانید محدودیت‌هایی برای چندین نوع از منابع سیستم تعیین کنید، از جمله:

  • nofile: تعداد فایل‌هایی که کانتینر می‌تواند باز کند.
  • nproc: تعداد پردازش‌هایی که یک کانتینر می‌تواند اجرا کند.
  • memlock: محدودیت در قفل کردن حافظه.
  • cpu: محدودیت در استفاده از پردازنده.

نحوه استفاده از ulimits در Docker Compose:

در Docker Compose، می‌توانید بخش ulimits را برای هر سرویس به طور جداگانه تنظیم کنید.

مثال استفاده از ulimits:

version: '3.8'

services:
  app:
    image: my-app
    ulimits:
      nofile:
        soft: 1024
        hard: 2048
      nproc:
        soft: 100
        hard: 200

در این مثال:

  • nofile: محدودیت تعداد فایل‌هایی که می‌توانند باز شوند.

    • soft: 1024: مقدار نرم (soft limit) برای تعداد فایل‌های باز 1024 است. این به این معنی است که کانتینر می‌تواند حداکثر 1024 فایل را به طور همزمان باز کند.
    • hard: 2048: مقدار سخت (hard limit) برای تعداد فایل‌های باز 2048 است. این مقدار می‌تواند توسط سیستم به طور موقت تغییر کند، اما نمی‌تواند از این مقدار تجاوز کند.
  • nproc: محدودیت تعداد پردازش‌ها.

    • soft: 100: محدودیت نرم برای تعداد پردازش‌های همزمان 100 است.
    • hard: 200: محدودیت سخت برای تعداد پردازش‌های همزمان 200 است.

مزایای استفاده از ulimits:

  1. حفاظت از منابع سیستم: با استفاده از ulimits می‌توانید از مصرف بیش از حد منابع سیستم جلوگیری کنید و اطمینان حاصل کنید که کانتینرها به منابع سیستم میزبان آسیب نمی‌زنند.

  2. مدیریت بهتر پردازش‌ها و فایل‌ها: برای سرویس‌هایی که نیاز به باز کردن تعداد زیادی فایل یا ایجاد پردازش‌های متعدد دارند، تنظیم ulimits می‌تواند به جلوگیری از بار اضافی بر روی سیستم کمک کند.

  3. پایداری سیستم: با تنظیم محدودیت‌های مناسب، می‌توانید از کرش کردن یا کاهش کارایی سیستم میزبان جلوگیری کنید.

نکات:

  • اگر ulimits را تنظیم نکنید، کانتینر به طور پیش‌فرض از تنظیمات سیستم میزبان استفاده می‌کند.
  • محدودیت‌های ulimits می‌توانند به صورت soft و hard تعیین شوند. مقدار soft به راحتی قابل تغییر است، در حالی که مقدار hard باید به وسیله سیستم تحمیل شود و نمی‌تواند از آن بیشتر شود.

نتیجه‌گیری:

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


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

logging

  1. تنظیمات لاگ‌ها برای هر سرویس: شما می‌توانید برای هر سرویس در Docker Compose تنظیمات مختلفی برای ذخیره‌سازی لاگ‌ها انجام دهید.
  2. انتقال لاگ‌ها به مقصدهای خارجی: می‌توانید لاگ‌ها را به مقصدهایی مانند فایل‌ها، سیستم‌های خارجی (مثلاً سیستم‌های لاگ مرکزی) یا حتی سیستم‌های خاص مانند syslog یا fluentd ارسال کنید.
  3. کنترل سطح لاگ‌ها: می‌توانید سطح لاگ‌ها را تنظیم کنید تا فقط اطلاعات مفید و مهم ثبت شوند.

نحوه استفاده از logging در Docker Compose:

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

مثال استفاده از logging در Docker Compose:

version: '3.8'

services:
  web:
    image: nginx
    logging:
      driver: "json-file"   # نوع درایور لاگ
      options:
        max-size: "10m"      # محدودیت سایز فایل لاگ
        max-file: "3"        # تعداد فایل‌های نگهداری شده
  app:
    image: my-app
    logging:
      driver: "syslog"      # ارسال لاگ‌ها به syslog
      options:
        syslog-address: "tcp://syslog.example.com:514"

توضیحات:

  1. driver: مشخص می‌کند که از چه درایوری برای ذخیره یا ارسال لاگ‌ها استفاده می‌شود. در اینجا دو نمونه از درایورها آمده است:

    • json-file: لاگ‌ها به فرمت JSON در فایل‌های محلی ذخیره می‌شوند.
    • syslog: لاگ‌ها به سرور Syslog ارسال می‌شوند.
  2. options: گزینه‌های اضافی برای پیکربندی درایور لاگ. در مثال بالا:

    • در سرویس web از درایور json-file استفاده شده و محدودیت‌هایی برای اندازه فایل لاگ (حداکثر 10 مگابایت) و تعداد فایل‌های نگهداری شده (حداکثر 3 فایل) تنظیم شده است.
    • در سرویس app از درایور syslog استفاده شده و آدرس سرور Syslog به طور مشخص تنظیم شده است.

انواع درایورهای لاگ:

  • json-file: این درایور پیش‌فرض است و لاگ‌ها را در فایل‌های JSON ذخیره می‌کند. این روش معمولاً برای ذخیره لاگ‌ها در فایل‌های محلی کاربرد دارد.
  • syslog: این درایور لاگ‌ها را به سیستم‌های Syslog ارسال می‌کند. این سیستم‌ها معمولاً برای تجزیه و تحلیل و جمع‌آوری لاگ‌ها در مقیاس بزرگ استفاده می‌شوند.
  • fluentd: این درایور برای ارسال لاگ‌ها به سیستم‌های جمع‌آوری لاگ مانند Fluentd استفاده می‌شود.
  • journald: این درایور لاگ‌ها را به سیستم journald ارسال می‌کند که معمولاً در سیستم‌های مبتنی بر Linux استفاده می‌شود.
  • gelf: این درایور برای ارسال لاگ‌ها به یک سرور Graylog Extended Log Format (GELF) استفاده می‌شود.
  • awslogs: این درایور برای ارسال لاگ‌ها به AWS CloudWatch Logs استفاده می‌شود.
  • splunk: این درایور برای ارسال لاگ‌ها به سرور Splunk استفاده می‌شود.

مزایای استفاده از logging:

  1. نظارت بهتر بر سیستم: با پیکربندی درست سیستم لاگ‌ها، می‌توانید به راحتی مشکلات را شناسایی و رفع کنید.
  2. مدیریت متمرکز لاگ‌ها: می‌توانید تمام لاگ‌های کانتینرهای مختلف را به یک سیستم مرکزی ارسال کنید و از آنجا نظارت کنید.
  3. ذخیره‌سازی و آرشیو لاگ‌ها: با تنظیم محدودیت‌هایی مانند سایز فایل و تعداد فایل‌ها، می‌توانید منابع سیستم را مدیریت کنید و از ذخیره‌سازی بی‌پایان لاگ‌ها جلوگیری کنید.
  4. یکپارچگی با ابزارهای نظارتی: با استفاده از درایورهای مانند syslog، fluentd، یا awslogs می‌توانید لاگ‌ها را به ابزارهای نظارتی قدرتمند ارسال کنید.

نتیجه‌گیری:

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


در Docker، cap_add و cap_drop برای مدیریت قابلیت‌های سیستم عامل (Linux capabilities) که به کانتینر داده می‌شود، استفاده می‌شوند. این قابلیت‌ها به طور پیش‌فرض به کانتینرها داده می‌شود، اما با استفاده از این دو گزینه می‌توان محدودیت‌هایی را اعمال کرد یا به کانتینر اجازه داد تا قابلیت‌های خاصی را به دست آورد.

1. cap_add:

با استفاده از cap_add می‌توانید قابلیت‌های خاصی را به کانتینر اضافه کنید. این قابلیت‌ها به شما این امکان را می‌دهند که کانتینر در سطح سیستم‌عامل، دسترسی‌های خاصی را داشته باشد. برای مثال، اضافه کردن قابلیت‌هایی مانند دسترسی به تغییرات در شبکه یا تنظیمات سیستم فایل.

مثال استفاده از cap_add:

version: '3.8'

services:
  app:
    image: my-app
    cap_add:
      - NET_ADMIN
      - SYS_TIME

در این مثال:

  • NET_ADMIN: به کانتینر اجازه می‌دهد تا تغییرات مربوط به تنظیمات شبکه را انجام دهد.
  • SYS_TIME: به کانتینر اجازه می‌دهد تا زمان سیستم را تغییر دهد.

2. cap_drop:

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

مثال استفاده از cap_drop:

version: '3.8'

services:
  app:
    image: my-app
    cap_drop:
      - NET_RAW
      - SYS_MODULE

در این مثال:

  • NET_RAW: قابلیت مربوط به ارسال و دریافت پکت‌های شبکه خام را از کانتینر حذف می‌کند.
  • SYS_MODULE: اجازه بارگذاری یا بارگیری ماژول‌های هسته را از کانتینر حذف می‌کند.

چرا باید از cap_add و cap_drop استفاده کنیم؟

  1. افزایش امنیت: با محدود کردن قابلیت‌ها و حذف قابلیت‌های غیر ضروری، می‌توانید سطح دسترسی کانتینر را کاهش دهید و امنیت سیستم را بالا ببرید.
  2. کاهش خطرات امنیتی: وقتی که قابلیت‌های اضافی که نیازی به آن‌ها نیست به کانتینر داده می‌شود، می‌تواند به آن آسیب‌پذیری‌های جدید اضافه کند. حذف این قابلیت‌ها می‌تواند این خطرات را کاهش دهد.
  3. کنترل دقیق‌تر: با اضافه یا حذف کردن قابلیت‌ها، شما دقیقاً می‌توانید دسترسی‌های کانتینر را به منابع و قابلیت‌های سیستم تنظیم کنید و نیازهای خاص خود را برآورده کنید.

قابلیت‌های رایج در cap_add و cap_drop:

  • NET_ADMIN: تغییرات در تنظیمات شبکه (مانند اضافه کردن یا حذف رابط‌های شبکه).
  • SYS_TIME: تغییر دادن زمان سیستم.
  • SYS_MODULE: بارگذاری یا بارگیری ماژول‌های هسته.
  • NET_RAW: ارسال و دریافت پکت‌های شبکه خام.
  • IPC_LOCK: قفل کردن حافظه برای استفاده در محاسبات حساس.
  • DAC_OVERRIDE: دور زدن مجوزهای دسترسی (مثلاً فایل‌ها و دایرکتوری‌ها).

نتیجه‌گیری:

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


در Docker Compose، گزینه devices به شما این امکان را می‌دهد که به کانتینر دسترسی به دستگاه‌های خاص موجود در سیستم میزبان (host) بدهید. این ویژگی به خصوص زمانی مفید است که شما نیاز دارید که کانتینر به دستگاه‌های فیزیکی خاصی مانند دوربین‌ها، درایوهای USB، یا دیگر دستگاه‌های مرتبط دسترسی پیدا کند.

با استفاده از devices، می‌توانید دستگاه‌هایی را که در سیستم میزبان در دسترس هستند، به کانتینر اختصاص دهید. این اجازه می‌دهد که کانتینر به این دستگاه‌ها دسترسی پیدا کرده و از آن‌ها استفاده کند.

devices

در فایل Docker Compose، می‌توانید دستگاه‌ها را به سرویس‌های مختلف اضافه کنید. مقدار devices معمولاً شامل مسیر دستگاه‌ها در سیستم میزبان است که به کانتینر اختصاص داده می‌شود.

مثال استفاده از devices:

version: '3.8'

services:
  app:
    image: my-app
    devices:
      - "/dev/sda:/dev/sda"  # اختصاص دستگاه /dev/sda به کانتینر
      - "/dev/video0:/dev/video0"  # اختصاص دوربین به کانتینر

در این مثال:

  • /dev/sda: این دستگاه می‌تواند یک دیسک سخت یا دستگاه ذخیره‌سازی باشد. با استفاده از این تنظیم، این دستگاه به کانتینر اختصاص داده می‌شود.
  • /dev/video0: این دستگاه معمولاً مربوط به یک دوربین یا دستگاه ویدیویی است. این تنظیم اجازه می‌دهد کانتینر به دوربین متصل به سیستم میزبان دسترسی داشته باشد.

قالب و نحوه تعریف دستگاه‌ها:

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

  • <host-device>:<container-device>

در اینجا:

  • <host-device>: مسیر دستگاه در سیستم میزبان است.
  • <container-device>: مسیر دستگاه در داخل کانتینر است. این معمولاً همان مسیر دستگاه در میزبان خواهد بود، اما می‌توانید آن را به طور متفاوتی تنظیم کنید.

کاربردهای رایج devices:

  1. دسترسی به دستگاه‌های ذخیره‌سازی: برای اتصال به دیسک‌های اضافی، حافظه‌های USB یا دستگاه‌های ذخیره‌سازی خاص.
  2. دستگاه‌های ورودی/خروجی (I/O): برای دسترسی به دستگاه‌هایی مانند دوربین‌ها، میکروفن‌ها، یا دیگر دستگاه‌های I/O که به سیستم میزبان متصل هستند.
  3. دستگاه‌های گرافیکی: برای دسترسی به GPU یا کارت گرافیک برای پردازش‌های محاسباتی یا پردازش‌های گرافیکی (مثلاً در استفاده از Docker برای ماشین‌های یادگیری عمیق یا گرافیک‌های سنگین).

مزایای استفاده از devices:

  1. دسترسی مستقیم به دستگاه‌ها: این امکان را به کانتینر می‌دهد که به دستگاه‌های فیزیکی سیستم میزبان دسترسی داشته باشد که ممکن است در غیر این صورت ممکن نباشد.
  2. انعطاف‌پذیری بیشتر در استفاده از کانتینرها: اگر شما نیاز دارید که کانتینر با سخت‌افزار خاصی تعامل داشته باشد (مثلاً پردازش ویدیو یا ذخیره‌سازی خاص)، می‌توانید دستگاه‌ها را از طریق devices اختصاص دهید.
  3. مدیریت راحت‌تر منابع: شما می‌توانید دقیقاً کنترل کنید که کدام دستگاه‌ها در دسترس کانتینرها قرار دارند، بدون اینکه لازم باشد کانتینر به همه دستگاه‌های سیستم میزبان دسترسی داشته باشد.

نکات:

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

نتیجه‌گیری:

استفاده از devices در Docker Compose به شما این امکان را می‌دهد که دستگاه‌های خاص سیستم میزبان را به کانتینرها اختصاص دهید. این قابلیت برای سناریوهایی که نیاز به دسترسی به دستگاه‌های فیزیکی مانند درایوهای USB، دوربین‌ها، یا GPU دارند، ضروری است. این ویژگی می‌تواند انعطاف‌پذیری و کارایی کانتینرها را افزایش دهد و به شما امکان می‌دهد کانتینرها را برای نیازهای خاص سخت‌افزاری پیکربندی کنید.

نظرات