---
title: Docker Compose depends_on لا ينتظر؟ إليك الحل (2026)
description: 'Docker هل depends_on في Compose لا ينتظر حتى تصبح الخدمة جاهزة؟ قم بإصلاح ذلك باستخدام condition: service_healthy، وفحص صحة (healthcheck) مناسب، و start_period في 2026.'
url: https://nerdleveltech.com/ar/docker-compose-depends-on-not-waiting
language: ar
date: '2026-07-27'
category: cloud-devops
tags:
  - docker compose
  - depends_on
  - healthcheck
  - service_healthy
  - containers
  - cloud-devops
  - startup order
markdown_url: https://nerdleveltech.com/ar/docker-compose-depends-on-not-waiting.md
attribution: 'Source: NerdLevelTech — https://nerdleveltech.com/ar/docker-compose-depends-on-not-waiting'
terms: https://nerdleveltech.com/llms.txt
---

# Docker Compose depends_on لا ينتظر؟ إليك الحل (2026)

إن `depends_on` العادية تنتظر فقط حتى **يعمل الحاوية (container is running)** الخاصة بالتبعية، وليس حتى تصبح الخدمة بداخلها **جاهزة (ready)** — لذا يتسابق تطبيقك مع قاعدة البيانات وينتهي الأمر بانهياره. الحل: استخدام الصيغة الطويلة مع `condition: service_healthy` بالإضافة إلى `healthcheck` حقيقي على التبعية.[^1][^2]

**ملخص:** `depends_on: [db]` يبدأ `db` قبل `web` ولكنه لا ينتظر حتى يبدأ Postgres في قبول الاستعلامات. انتقل إلى الصيغة الطويلة (`depends_on: { db: { condition: service_healthy } }`) وامنح `db` فحص حالة `healthcheck` مثل `pg_isready`. اضبط `start_period` بقيمة كافية حتى لا يتم اعتبار قاعدة البيانات التي تبدأ ببطء غير صحية في وقت مبكر جدًا. إذا رأيت `dependency failed to start: container ... is unhealthy`، فهذا يعني أن فحص حالة التبعية قد فشل أو أنه مفقود. يتم احترام `depends_on` بواسطة `Docker compose up` ولكن يتم تجاهلها بواسطة `Docker stack deploy` الخاصة بـ Swarm.

## ما ستتعلمه

- لماذا لا ينتظر `depends_on` حتى تصبح خدمتك *جاهزة*
- الفرق بين `service_started` و `service_healthy` و `service_completed_successfully`
- كيفية إضافة `healthcheck` وربط عملية التشغيل بها (مع مثال عملي)
- لماذا تعلق الحاوية في حالة `health: starting` ولا تتقدم أبدًا
- ماذا يعني `dependency failed to start: container is unhealthy` وكيفية إصلاحه
- قيم `interval` و `timeout` و `retries` و `start_period` و `start_interval` التي يجب استخدامها
- ما إذا كان `depends_on` يعمل مع `Docker compose run` و `Docker stack deploy`
- متى تلجأ إلى استخدام `wait-for-it.sh` أو إعادة المحاولة على مستوى التطبيق بدلاً من ذلك

## لماذا لا ينتظر Docker compose depends\_on خدمتي؟

لأن "بدأت" لا تعني "جاهزة". التوثيق الرسمي لـ Docker صريح في ذلك: "عند التشغيل، لا ينتظر Compose حتى تصبح الحاوية 'جاهزة'، بل فقط حتى تبدأ في العمل."[^2] مع الصيغة القصيرة، يقوم Compose بإنشاء التبعية أولاً ثم يبدأ الخدمة المعتمدة عليها فوراً — فهو لا ينتظر حتى تصبح التبعية صحية (healthy).[^1]

هذا التمييز مهم جداً للخدمات التي تحفظ الحالة (stateful services). حاوية Postgres تبلغ عن أنها "تعمل" في غضون أجزاء من الثانية، ولكن عملية قاعدة البيانات تحتاج إلى وقت إضافي قبل أن تقبل استعلامات SQL. يحاول تطبيقك الاتصال في هذه الفجوة الزمنية ثم ينهار. هذه الصيغة القصيرة هي الفخ:

```yaml
services:
  web:
    build: .
    depends_on:
      - db     # only waits for the container to START, not to be READY
  db:
    image: postgres:18
```

يضمن Compose إنشاء `db` قبل `web`، وهذا كل شيء. وكما ورد في التوثيق: "مع الصيغة القصيرة، لا ينتظر Compose خدمات التبعية حتى تصبح 'صحية' قبل بدء الخدمة المعتمدة عليها."[^1] لانتظار الجاهزية، تحتاج إلى الصيغة الطويلة بالإضافة إلى فحص الحالة (healthcheck).

## ما الفرق بين service\_started و service\_healthy و service\_completed\_successfully؟

إنها القيم الثلاث لـ `condition` في صيغة `depends_on` الطويلة، وهي تحدد معنى "تم الاستيفاء" بالنسبة للتبعية:[^1][^2]

- **`service_started`** — حاوية التبعية قيد التشغيل. هذا يطابق الصيغة القصيرة: الترتيب فقط، دون التحقق من الجاهزية.
- **`service_healthy`** — أبلغ الـ `healthcheck` الخاص بالتبعية أنها **سليمة (healthy)**. استخدم هذا لقواعد البيانات، والوسطاء (brokers)، والمخازن المؤقتة (caches) التي تحتاج وقتاً للإحماء.
- **`service_completed_successfully`** — انتهت التبعية من التشغيل و**خرجت بالكود 0**. استخدم هذا لمهام التهيئة أو الترحيل (migration) التي تُنفذ لمرة واحدة ويجب أن تنتهي قبل بدء التطبيق.

| الشرط                            | ينتظر حتى            | هل يحتاج healthcheck؟ | الاستخدام النموذجي                                |
| -------------------------------- | -------------------- | --------------------- | ------------------------------------------------- |
| `service_started`                | تشغيل الحاوية        | لا                    | خدمات غير مرتبطة بقوة                             |
| `service_healthy`                | نجاح الـ Healthcheck | **نعم**               | قواعد البيانات، الوسطاء، المخازن المؤقتة          |
| `service_completed_successfully` | كود الخروج 0         | لا                    | الترحيلات (Migrations)، الـ seeders، مهام التهيئة |

فقط `service_healthy` هو الذي ينتظر الجاهزية الفعلية، وهو يعمل **فقط إذا كانت التبعية تحدد healthcheck**. بدون ذلك، لا توجد حالة صحية لاستيفائها — وهذا هو السبب الأكثر شيوعاً لكون بوابات بدء التشغيل "لا تفعل شيئاً".[^1]

## كيف أجعل depends\_on ينتظر حتى تصبح الخدمة سليمة (healthy)؟

خطوتان: أضف `healthcheck` إلى التبعية، ثم أشر إليها باستخدام `condition: service_healthy`. هذا هو المثال الرسمي لـ Docker، حيث تنتظر خدمة `web` وصول `db` لحالة سليمة، وبدء تشغيل `Redis`:[^2]

```yaml
services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
        restart: true
      redis:
        condition: service_started
  redis:
    image: redis
  db:
    image: postgres:18
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 10s
      retries: 5
      start_period: 30s
      timeout: 10s
```

الآن ينتظر Compose نجاح الـ healthcheck الخاص بـ `db` قبل إنشاء `web`.[^2] فحص `pg_isready` يعيد نتيجة "نجاح" فقط عندما يكون Postgres يقبل الاتصالات فعلياً، وبذلك يختفي سباق التشغيل. الرمز `$$` يقوم بعمل escape للمتغير بحيث يمرر Compose قيمة `$POSTGRES_USER` إلى الشل (shell) داخل الحاوية بدلاً من معالجتها بنفسه.

الخيار الفرعي الاختياري `restart: true` (الذي تم تقديمه في Docker Compose 2.17.0) يعني أنه إذا تمت إعادة تشغيل `db` بواسطة عملية Compose صريحة مثل `Docker compose restart`، فسيتم إعادة تشغيل `web` أيضاً، ليعيد إنشاء اتصالاته.[^1] وهناك خيار فرعي مرتبط، وهو `required: false` (Docker Compose 2.20.0)، والذي يخفض درجة التبعية المفقودة من "خطأ" إلى "تحذير".[^1] كل هذا محدث حتى إصدار Docker Compose **v5.3.1**، الذي صدر في 7 يوليو 2026.[^3]

## لماذا تظل الحاوية الخاصة بي عالقة في حالة "health: starting"؟

تظل الحاوية في حالة `health: starting` حتى ينجح أول فحص صحي (healthcheck) أو حتى تنتهي فترة `start_period` وتبدأ الإخفاقات في الاحتساب. إذا لم تبدأ الخدمة التابعة أبداً وكانت التبعية عالقة في حالة "starting"، فإن الأسباب المعتادة هي:

- **التبعية لا تحتوي على `healthcheck` على الإطلاق**، ولكن هناك شيء يشير إليها باستخدام `condition: service_healthy`. بدون وجود فحص (probe)، لا يمكنها أبدًا الوصول إلى حالة `healthy`، لذا تظل البوابة في حالة انتظار — أو تفشل — إلى الأبد.[^1]
- **أمر فحص الصحة (healthcheck command) خاطئ** — الملف الثنائي (binary) غير موجود في الصورة، أو أن الاختبار لا يعيد أبدًا القيمة exit 0.
- **`start_period` قصيرة جدًا**، لذا فإن قاعدة البيانات التي تحتاج إلى 40 ثانية للتهيئة يتم تعليمها بأنها غير صحية (unhealthy) قبل أن تنتهي.

حالات الصحة في Docker هي `starting`، و `healthy`، و `unhealthy`، وتعتمد على كود الخروج الخاص بالفحص: **`0` يعني صحي، و `1` يعني غير صحي**. الإخفاقات التي تحدث *خلال* `start_period` لا تُحتسب ضمن حد إعادة المحاولة، والنجاح خلال تلك الفترة ينهي فترة السماح مبكرًا. تحقق من الحالة الحالية باستخدام `Docker inspect --format '{{.State.Health.Status}}' <container>` أو تابعها مباشرة عبر `Docker compose ps`.

## ماذا يعني "dependency failed to start: container is unhealthy"؟

هذا يعني أن بوابة `condition: service_healthy` قد فشلت: استنفد فحص الصحة الخاص بالتبعية عدد `retries` (إعادة المحاولات) دون أن ينجح أبدًا (أو أن التبعية لا تحتوي على فحص صحة لتحقيق الشرط).[^4] يقوم Compose الحديث بالفشل سريعًا هنا بدلاً من التعليق إلى أجل غير مسمى. لإصلاح ذلك، تعامل مع التبعية نفسها:

1. **تأكد من أن التبعية تحتوي فعليًا على `healthcheck`.** إذا كانت مشار إليها بـ `service_healthy` ولكنها لا تحدد أي فحص، قم بإضافة واحد.
2. **قم بتشغيل الفحص يدويًا** داخل الحاوية: `Docker compose exec db pg_isready -U postgres`. إذا فشل هناك، فإن أمر الاختبار الخاص بك خاطئ.
3. **ارفع قيمة `start_period`** للخدمات التي تستغرق وقتًا في التشغيل. غالبًا ما تحتاج خدمة Postgres الباردة أو خدمة JVM إلى 60 ثانية أو أكثر قبل أول فحص ناجح.
4. **خفف قيود `retries`/`interval`** إذا كانت الخدمة صحية ولكنها غير مستقرة تحت الضغط أثناء التشغيل.

هذا الخطأ هو عرض لحالة صحة *التبعية*، وليس الخدمة المعتمدة عليها — قم دائمًا بتصحيح أخطاء الخدمة المذكورة في الرسالة.

## ما هي قيم interval و retries و start\_period التي يجب أن أستخدمها؟

ابدأ من القيم الافتراضية لـ HEALTHCHECK في Docker Engine وقم بضبطها من هناك. القيم الافتراضية هي `interval` **30s**، و `timeout` **30s**، و `retries` **3**، و `start_period` **0s**.[^5] القيمة الافتراضية لـ `start_period` التي تساوي صفرًا هي السبب في اعتبار قواعد البيانات غير صحية عند التشغيل البارد — قم بتعيينها دائمًا.

نقاط بداية منطقية حسب نوع الخدمة:

- **قواعد البيانات (Postgres, MySQL):** `interval: 10s`, `timeout: 5s`, `retries: 5`, `start_period: 30s–60s`.
- **واجهات HTTP APIs:** اختبار `curl -f http://localhost:PORT/health`, `interval: 15s`, `timeout: 5s`, `retries: 3`, `start_period: 20s`.
- **خدمات JVM الثقيلة / خدمات الذاكرة المخبئية الباردة:** ارفع `start_period` إلى 60s–120s.

هناك أيضًا `start_interval`، والتي تحدد عدد مرات تشغيل الفحص *خلال* `start_period` — بحيث يمكنك الفحص كل ثانية عند التشغيل ثم العودة إلى `interval` الأبطأ بمجرد أن تصبح الخدمة صحية. يتطلب ذلك **Docker Compose 2.20.2+ و Docker Engine 25.0+**:[^6]

```yaml
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 30s        # steady-state cadence
      timeout: 5s
      retries: 5
      start_period: 60s    # grace window; failures here don't count
      start_interval: 1s   # poll every 1s during the grace window
```

يفضل استخدام صيغة exec `["CMD", "bin", "arg"]` عندما لا تحتاج إلى shell، وصيغة `["CMD-SHELL", "..."]` عندما تحتاج إلى pipes أو متغيرات بيئة. استخدم `test: ["NONE"]` لتعطيل فحص الحالة (healthcheck) الذي ورثته الصورة من صورتها الأساسية.[^5]

## هل يعمل depends\_on مع Docker compose run و Docker stack deploy؟

ليس في كل مكان. `depends_on` هي ميزة تنسيق خاصة بـ Compose، وهناك سياقان لا يلتزمان بها بنفس الطريقة التي يفعلها `Docker compose up`:

- **`Docker stack deploy` (وضع Swarm) يتجاهل `depends_on` تماماً** — دون أي تحذير. لا يمتلك Swarm مفهوماً لبدء التشغيل المرتب، لذا يتم إسقاط التبعيات المعلنة بصمت.[^7] في Swarm، يجب عليك جعل الخدمات مرنة تجاه التبعيات المفقودة بدلاً من ذلك.
- **`Docker compose run <service>`** يبدأ خدمات depends\_on ولكن **لا** ينتظر تقارير فحص الحالة لتكون سليمة (healthy)، بينما يقوم `--no-deps` بتخطي بدء تشغيلها تماماً.[^8]

كما أن `depends_on` تقوم بترتيب الخدمات **داخل مشروع Compose واحد فقط** — ولا يمكنها ترتيب الحاويات التي تشغلها بأوامر `Docker run` منفصلة أو في مشروع آخر.

## مقارنة بين depends\_on و wait-for-it.sh وإعادة المحاولة على مستوى التطبيق (app-level retries)

الثلاثة يحلون مشكلة "انتظار الجاهزية"، ولكن في طبقات مختلفة:

- **`depends_on` + `service_healthy`** هو الخيار التصريحي المدمج. وهو الخيار الافتراضي الصحيح لأن فحص الجاهزية يكون مرتبطاً بالتبعية وكل تابع يرثه.[^2]
- **سكربتات التغليف (Wrapper scripts)** مثل `wait-for-it.sh`، أو `wait-for`، أو `dockerize` تقوم بالتوقف عند منفذ TCP مفتوح قبل تشغيل تطبيقك. هي بسيطة، ولكن فتح المنفذ أضعف من فحص الحالة الحقيقي: فمثلاً Postgres يقبل اتصالات TCP قبل أن يقبل الاستعلامات، لذا قد ينجح فحص المنفذ في وقت مبكر جداً.
- **إعادة المحاولة على مستوى التطبيق (Application-level retries)** هي الطبقة الأكثر متانة. إرشادات Docker طويلة الأمد هي جعل التطبيق مرناً — إعادة الاتصال مع تراجع تدريجي (backoff) — لأن ترتيب بدء التشغيل وحده لا يمكنه ضمان الجاهزية عند إعادة التشغيل في منتصف العمل. استخدام [قاطع دائرة (circuit breaker) أو غلاف إعادة محاولة](https://nerdleveltech.com/nodejs-circuit-breaker-opossum-TypeScript-tutorial) ضروري في بيئة الإنتاج بغض النظر عن إعدادات Compose الخاصة بك.

أفضل الممارسات في 2026: استخدم `service_healthy` لبدء تشغيل نظيف محلياً وفي بيئة CI، و*لا تزال* بحاجة لإضافة منطق إعادة المحاولة في التطبيق حتى لا يتوقف service عند حدوث failover لقاعدة البيانات في الساعة 3 فجراً.

## الأسئلة الشائعة

**لماذا لا ينتظر depends\_on حتى تصبح قاعدة البيانات الخاصة بي جاهزة؟** الصيغة القصيرة (`depends_on: [db]`) تنتظر فقط بدء تشغيل الحاوية، وليس قبول الخدمة للاتصالات.[^1] استخدم الصيغة الطويلة مع `condition: service_healthy` بالإضافة إلى فحص حالة (healthcheck) على قاعدة البيانات.

**ما الفرق بين service\_started و service\_healthy؟** `service_started` ينتظر فقط أن تكون الحاوية قيد التشغيل (مثل الصيغة القصيرة). أما `service_healthy` فينتظر حتى يبلغ فحص حالة التبعية أنها سليمة، وهذا يتطلب من التبعية تعريف `healthcheck`.[^1]

**كيف أجعل Docker Compose ينتظر حتى تصبح الخدمة سليمة (healthy)؟** أضف `healthcheck` إلى التبعية (بالنسبة لـ Postgres، استخدم `pg_isready`)، ثم أشر إليها باستخدام `depends_on: { db: { condition: service_healthy } }`. سيقوم Compose بحظر الخدمة التابعة حتى ينجح الفحص.[^2]

**لماذا تظل الحاوية الخاصة بي عالقة في حالة "health: starting"؟** لأن فحص الصحة (healthcheck) لا يعيد أبداً القيمة exit 0 — وعادة ما يكون ذلك بسبب فقدان فحص الصحة، أو أمر اختبار خاطئ، أو أن `start_period` قصير جداً بالنسبة لخدمة تستغرق وقتاً في التشغيل. الحالات هي `starting`، و `healthy`، و `unhealthy`؛ حيث تعني القيمة `0` أنها سليمة، والقيمة `1` تعني أنها غير سليمة.[^5]

**كيف أصلح خطأ "dependency failed to start: container is unhealthy"؟** فشل فحص الصحة الخاص بالتبعية في محاولات إعادة التشغيل أو أنه غير موجود. أضف أو أصلح فحص الصحة، وقم بتشغيل الفحص يدوياً للتأكد من نجاحه، وارفع قيمة `start_period`\_\_ للخدمات بطيئة التشغيل.[^4]

[^4]

[^4][^5]

[^5]

[^5][^7]

[^7]

## [^7]الخلاصة

إن `depends_on` بمفردها تقوم فقط بترتيب بدء تشغيل الحاويات — وهي لا تنتظر أبداً الجاهزية. انتقل إلى الصيغة الطويلة، واعتمد على `condition: service_healthy`، وامنح كل تبعية ذات حالة (stateful) فحص صحة `healthcheck` حقيقي مع `start_period` سخي، وحافظ على منطق إعادة المحاولة (retry logic) داخل التطبيق للحالات التي لا يستطيع Compose تغطيتها. إذا كنت تقوم بربط هذا في بيئة إنتاج، فادمجها مع [إعداد Docker Compose HTTPS](https://nerdleveltech.com/caddy-reverse-proxy-Docker-compose-production-https-tutorial) محصن، وتعامل مع فحوصات الصحة بنفس الطريقة التي تتعامل بها مع [فحوصات الجاهزية في Kubernetes عند النشر بدون توقف](https://nerdleveltech.com/Kubernetes-zero-downtime-deployments-tutorial). وبالنسبة لتبعيات قواعد البيانات تحديداً، فإن وجود [طبقة تجميع اتصالات (connection-pooling layer)](https://nerdleveltech.com/production-postgres-pooling-pgbouncer-Supabase-supavisor-tutorial) مرنة لا يقل أهمية عن ترتيب بدء التشغيل.

[^1]: وثائق Docker — "تعريف الخدمات في Compose"، `depends_on` (الصيغة القصيرة والطويلة؛ تم تقديم `restart` في الإصدار 2.17.0، و `required` في الإصدار 2.20.0). <https://docs.Docker.com/reference/compose-file/services/#depends_on>

[^2]: وثائق Docker — "التحكم في ترتيب التشغيل والإغلاق في Compose" (Compose لا ينتظر حتى يصبح الحاوية "جاهزة"؛ `service_started` / `service_healthy` / `service_completed_successfully`؛ مثال نموذجي). <https://docs.Docker.com/compose/how-tos/startup-order/>

[^3]: إصدارات GitHub لـ Docker/compose — الإصدار v5.3.1، صدر في 7 يوليو 2026 (المستقر حالياً). <https://GitHub.com/Docker/compose/releases/tag/v5.3.1>

[^4]: مشكلة Docker/compose رقم 11474 وتقارير المجتمع — "فشل بدء التبعية: الحاوية ... غير سليمة (unhealthy)" تحدث عندما يفشل فحص الحالة (healthcheck) لتبعية `service_healthy` في محاولات إعادة التشغيل أو يكون مفقوداً. <https://GitHub.com/Docker/compose/issues/11474>

[^5]: وثائق Docker — مرجع Dockerfile `HEALTHCHECK` (القيم الافتراضية: الفاصل الزمني 30 ثانية، المهلة 30 ثانية، عدد المحاولات 3، فترة البدء 0 ثانية؛ الخروج 0 = سليم، 1 = غير سليم؛ `CMD` مقابل `CMD-SHELL` مقابل `NONE`). <https://docs.Docker.com/reference/dockerfile/#healthcheck>

[^6]: مشكلة Docker/compose رقم 10830 — يتطلب `start_interval` إصدار Docker Compose 2.20.2+ وإصدار Docker Engine 25.0+. <https://GitHub.com/Docker/compose/issues/10830>

[^7]: مشكلة moby/moby رقم 40364 ومشكلة Docker/compose رقم 13819 — يتم تجاهل `depends_on` بواسطة `Docker stack deploy` في وضع Swarm. <https://GitHub.com/moby/moby/issues/40364>

[^8]: مشكلة Docker/compose رقم 7681 — يقوم `Docker compose run` بتشغيل التبعيات ولكنه لا ينتظر فحوصات الحالة (healthchecks) الخاصة بها؛ بينما يقوم `--no-deps` بتخطيها. <https://GitHub.com/Docker/compose/issues/7681>
