Docker: مقدمة إلى Docker Compose

آخر تحديث: 2026-08-26

5 أوامر docker run اختُزلت إلى docker compose up واحد — Compose يحوّل نشر الحاويات المتعددة من العمليات اليدوية إلى التكوين التعريفي.

1. ما ستتعلمه



2. قصة حقيقية لمطور

(1) نقطة الألم: تشغيل 5 أوامر docker run في كل مرة أصحح فيها

في كل مرة تصحح فيها أليس، تضطر إلى كتابة خمسة أوامر docker run يدويًا لبدء الحاويات الأربعة — Web و DB و Cache و Queue و Worker — التي تشمل العديد من المعاملات، وتتطلب الترتيب الصحيح، وتجعل من السهل الخطأ في كتابة متغيرات البيئة. مرة، نسيت تضمين --network app-net وقضت ساعة في استكشاف سبب عدم قدرة حاوية Web على الاتصال بقاعدة البيانات.

(2) حلول التكوين التعريفي في Docker Compose

كتب بوب ملف docker-compose.yml، لذا من الآن فصاعدًا، تحتاج أليس فقط إلى docker compose up -d.

YAML
# docker-compose.yml - ملف واحد يعرف كل شيء
services:
  web:
    image: nginx:alpine
    ports: ["8080:80"]
    depends_on:
      - api
  api:
    build: .
    environment:
      - DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=myapp
    volumes:
      - pg-data:/var/lib/postgresql/data

volumes:
  pg-data:

networks:
  default:
    name: app-net

(3) الفائدة: 5 أوامر ← أمر واحد

تم تقليل النشر من 5 أوامر بالإضافة إلى التكوين اليدوي إلى أمر واحد فقط docker compose up -d. يمكن للقادمين الجدد تشغيل المشروع بالكامل في 5 دقائق.



3. هيكل docker-compose.yml

(1) الحقول الثلاثة الرئيسية

YAML
# هيكل docker-compose.yml
services:    # تعريفات الحاويات (مطلوب)
  web:
    image: nginx:alpine

volumes:     # إعلانات وحدات التخزين المسماة (اختياري)
  pg-data:

networks:    # إعلانات الشبكات المخصصة (اختياري)
  app-net:

(2) مقارنة docker run مقابل docker compose

البُعد docker run docker compose
طريقة التعريف وسائط سطر الأوامر ملف YAML
قابلية التكرار منخفضة (تعتمد على ذاكرة المشغل) عالية (يمكن إيداع الملفات في Git)
حاويات متعددة أوامر متعددة ملف واحد
الشبكة/وحدة التخزين إنشاء يدوي إدارة تعريفية تلقائية
متغيرات البيئة وسائط -e متعددة env_file أو كتلة environment
التحكم في الإصدار ✅ YAML يدعم git diff


4. شرح مفصل لإعدادات الخدمات

(1) حقول الخدمة الشائعة

الحقل الغرض مثال
image استخدام صورة موجودة image: nginx:alpine
build البناء من Dockerfile build: . أو build: { context: ., dockerfile: Dockerfile.prod }
ports تعيين المنفذ ports: ["8080:80"]
environment متغيرات البيئة environment: { POSTGRES_PASSWORD: secret }
env_file تحميل المتغيرات من ملف env_file: .env
volumes تركيب وحدة تخزين volumes: [pg-data:/var/lib/postgresql/data]
depends_on تبعيات البدء depends_on: [db]
restart سياسة إعادة التشغيل restart: unless-stopped
networks شبكة محددة networks: [app-net]
healthcheck فحص الصحة healthcheck: { test: ["CMD", "curl", "-f", "http://localhost/"] }

▶ مثال: كتابة أبسط ملف Compose (الصعوبة: ⭐)

YAML
# docker-compose.yml مصغر
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
BASH
# البدء بـ compose
docker compose up -d

# التحقق
docker compose ps


5. التحكم في التبعيات: depends_on

(1) ثلاث استراتيجيات للانتظار

الاستراتيجية الصيغة الانتظار حتى الوصف
started (افتراضي) depends_on: [db] بدء الحاوية جاهزية الخدمة غير مضمونة
healthy depends_on: { db: { condition: service_healthy } } اجتياز فحص الصحة ✅ موصى به للاستخدام في الإنتاج
completed depends_on: { init: { condition: service_completed_successfully } } إنهاء الحاوية بنجاح مهمة تهيئة

▶ مثال: التحكم في التبعيات باستخدام depends_on و healthcheck (الصعوبة: ⭐⭐)

YAML
services:
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - pg-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  api:
    build: .
    environment:
      DATABASE_URL: postgresql://postgres:secret@db:5432/myapp
    depends_on:
      db:
        condition: service_healthy

volumes:
  pg-data:
💡 نصيحة: depends_on: [db] (الافتراضي) ينتظر فقط بدء حاوية DB؛ لا ينتظر حتى يكون PostgreSQL جاهزًا. قد تحاول API الاتصال قبل أن يكون DB جاهزًا وتفشل. condition: service_healthy يضمن أن API لا تبدأ حتى يكون PostgreSQL جاهزًا فعليًا.



6. إعلانات وحدات التخزين والشبكات

▶ مثال: إعلان وحدات التخزين والشبكات (الصعوبة: ⭐⭐)

YAML
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./src:/usr/share/nginx/html:ro    # تركيب Bind (للقراءة فقط)
      - nginx-cache:/var/cache/nginx       # وحدة تخزين مسماة
    networks:
      - frontend
      - backend

  api:
    build: .
    networks:
      - backend
      - database

  db:
    image: postgres:15-alpine
    volumes:
      - pg-data:/var/lib/postgresql/data
    networks:
      - database

volumes:
  pg-data:
  nginx-cache:

networks:
  frontend:
  backend:
  database:
    internal: true   # لا وصول خارجي


7. إدارة متغيرات البيئة

(1) مقارنة الطرق الثلاث

الطريقة الصيغة حالات الاستخدام
كتلة environment environment: { KEY: VALUE } عدد قليل من المتغيرات الثابتة
env_file env_file: .env متغيرات متعددة/معلومات حساسة
متغيرات Shell environment: { KEY: ${VAR} } تكوين ديناميكي

▶ مثال: env_file واستبدال المتغيرات (الصعوبة: ⭐⭐)

YAML
# docker-compose.yml مع استبدال المتغيرات
services:
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD:-defaultsecret}
      POSTGRES_DB: ${DB_NAME:-myapp}
    env_file:
      - .env.db

  api:
    build: .
    environment:
      DATABASE_URL: postgresql://postgres:${DB_PASSWORD:-defaultsecret}@db:5432/${DB_NAME:-myapp}
BASH
# .env.db
POSTGRES_USER=appuser
POSTGRES_PASSWORD=secret123
📌 نقطة أساسية: صيغة ${VAR:-default}: إذا لم يتم تعيين VAR، استخدم القيمة الافتراضية. بهذه الطريقة، يحتوي ملف compose على قيم افتراضية، يتم تجاوزها بواسطة ملف .env في بيئة الإنتاج.



8. أوامر Docker Compose الشائعة

الأمر الوظيفة مثال
docker compose up -d بدء جميع الخدمات (في الخلفية) docker compose up -d
docker compose down إيقاف وحذف جميع الحاويات/الشبكات docker compose down
docker compose down -v حذف وحدات التخزين في نفس الوقت docker compose down -v
docker compose ps عرض حالة الخدمات docker compose ps
docker compose logs عرض السجلات docker compose logs -f api
docker compose exec الدخول إلى الحاوية docker compose exec api bash
docker compose build إعادة بناء الصورة docker compose build api
docker compose pull جلب أحدث صورة docker compose pull
docker compose config التحقق وعرض التكوين المدمج docker compose config

▶ مثال: البدء بـ docker compose up -d (الصعوبة: ⭐)

BASH
# بدء جميع الخدمات في وضع منفصل
docker compose up -d

# متابعة سجلات جميع الخدمات
docker compose logs -f

# متابعة سجلات خدمة محددة
docker compose logs -f api

▶ مثال: الدخول إلى حاوية باستخدام docker compose exec (الصعوبة: ⭐)

BASH
# فتح shell في حاوية خدمة api
docker compose exec api bash

# تشغيل أمر واحد
docker compose exec db psql -U postgres -d myapp

▶ مثال: التنظيف بـ docker compose down (الصعوبة: ⭐)

BASH
# إيقاف وإزالة الحاويات + الشبكات
docker compose down

# أيضًا إزالة وحدات التخزين المسماة (تحذير: يحذف البيانات)
docker compose down -v

# أيضًا إزالة الصور
docker compose down --rmi all


9. مثال كامل: WordPress + MySQL

YAML
# ============================================
# docker-compose.yml: WordPress + MySQL
# الميزات: وحدات تخزين، شبكات، depends_on، healthcheck
# ============================================

services:
  wordpress:
    image: wordpress:6.4-php8.2-apache
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:-wppass123}
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp-content:/var/www/html/wp-content
    depends_on:
      mysql:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - wp-net

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootsecret}
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: ${DB_PASSWORD:-wppass123}
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - wp-net

volumes:
  mysql-data:
  wp-content:

networks:
  wp-net:
BASH
# النشر
docker compose up -d

# التحقق
docker compose ps
docker compose logs -f wordpress

# الوصول إلى WordPress
# افتح http://localhost:8080 في المتصفح

# التنظيف (يحتفظ بالبيانات)
docker compose down

# تنظيف كل شيء (يحذف البيانات)
docker compose down -v

❓ أسئلة شائعة

س أي إصدار يجب استخدامه لـ docker-compose.yml؟
ج Docker Compose V2 الجديد لم يعد يتطلب حقل version. يمكنك البدء في الكتابة مباشرة من services:. إذا رأيت "version: "3.8 في الدروس القديمة، يمكنك حذفه — V2 يتجاهله.
س هل depends_on يضمن أن الخدمة جاهزة؟
ج افتراضيًا، depends_on: [db] يضمن فقط بدء حاوية db؛ لا يضمن أن PostgreSQL جاهز. يجب إضافة condition: service_healthy للانتظار حتى يجتاز فحص الصحة. هذا هو الفخ الأكثر شيوعًا لمبتدئي Compose — الخدمة تبدأ، لكن الاتصال يفشل لأن التبعية غير جاهزة.
س كيف تُدار متغيرات البيئة في ملفات Compose؟
ج إدارة ثلاثية الطبقات: ① كتلة environment في docker-compose.yml (قيم افتراضية غير حساسة)؛ ② ملف .env (قيم خاصة بالبيئة، غير مودعة في Git)؛ ③ صيغة ${VAR:-default} (كاحتياط للقيم الافتراضية). لا تدرج كلمات مرور حساسة في YAML؛ استخدم ملف .env + .gitignore بدلاً من ذلك.
س هل docker compose down يحذف وحدات تخزين البيانات؟
ج افتراضيًا، لا. docker compose down فقط الحاويات والشبكات تُحذف؛ وحدات التخزين المسماة تُحتفظ بها. يجب إضافة -v لحذف وحدات التخزين. لا تستخدم down -v في بيئات الإنتاج؛ استخدم فقط down.
س ما هو الغرض من اسم مشروع Compose؟
ج اسم المشروع يعزل موارد تطبيقات Compose المختلفة. افتراضيًا، يستخدم اسم الدليل الحالي. docker compose -p myproject up يمكنك تخصيص اسم المشروع. يمكن تشغيل مشاريع Compose متعددة على نفس الجهاز دون تداخل.

📖 ملخص


📝 تمارين

  1. تمرين أساسي (الصعوبة: ⭐): اكتب ملف docker-compose.yml لمجموعة LEMP في المرحلة الأولى (Nginx+PHP+MySQL) وابدأه باستخدام docker compose up -d.
  2. تمرين متقدم (الصعوبة: ⭐⭐): أضف depends_on و healthcheck إلى ملف compose لضمان أن PHP-FPM يبدأ فقط بعد أن يكون MySQL جاهزًا.
  3. تحدٍ (الصعوبة: ⭐⭐⭐): استخدم docker compose logs لاستكشاف خدمة فشلت في البدء، وحلل السجلات لتحديد السبب الجذري، وأصلح المشكلة.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%