Docker: مقدمة إلى Docker Compose
آخر تحديث: 2026-08-26
5 أوامر docker run اختُزلت إلى docker compose up واحد — Compose يحوّل نشر الحاويات المتعددة من العمليات اليدوية إلى التكوين التعريفي.
1. ما ستتعلمه
- هيكل وصيغة docker-compose.yml
- تعريف الخدمة والتحكم في التبعيات
- الإدارة التعريفية لوحدات التخزين والشبكات
- استراتيجيات إدارة متغيرات البيئة
- أوامر Docker Compose الشائعة
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 متعددة على نفس الجهاز دون تداخل.📖 ملخص
- docker-compose.yml: يستبدل أوامر
docker runالمتعددة بـ YAML تعريفي - الحقول الثلاثة الرئيسية: services (تعريفات الحاويات)، volumes (وحدات تخزين دائمة)، و networks (الشبكات)
depends_on+condition: service_healthyيضمن أن التبعيات جاهزة فعليًا- متغيرات البيئة: إدارة ثلاثية الطبقات باستخدام كتلة
environmentوenv_fileو${VAR:-default} docker compose up -dبدء بنقرة واحدة،docker compose downتنظيف بنقرة واحدةdocker compose configالتحقق من صيغة ملفات التكوين لتجنب اكتشاف الأخطاء في وقت التشغيل
📝 تمارين
- تمرين أساسي (الصعوبة: ⭐): اكتب ملف
docker-compose.ymlلمجموعة LEMP في المرحلة الأولى (Nginx+PHP+MySQL) وابدأه باستخدامdocker compose up -d. - تمرين متقدم (الصعوبة: ⭐⭐): أضف
depends_onوhealthcheckإلى ملفcomposeلضمان أن PHP-FPM يبدأ فقط بعد أن يكون MySQL جاهزًا. - تحدٍ (الصعوبة: ⭐⭐⭐): استخدم
docker compose logsلاستكشاف خدمة فشلت في البدء، وحلل السجلات لتحديد السبب الجذري، وأصلح المشكلة.