SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-13

دليل أوامر Docker Compose للخوادم الحقيقية

مرجع عملي لأوامر Compose V2 اليومية: التشغيل، تطبيق التغييرات، السجلات، الصدفة، الشبكات، المجلدات والتنظيف الآمن، مع تنبيه إلى خطأ docker-compose.

أوامر Compose التي تستخدمها فعلياً

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

يستخدم كل ما يرد هنا Compose V2: docker compose مع مسافة، وليس البرنامج النصي القديم docker-compose. الإصدار V2 إضافة Go تُثبَّت مع Docker Engine، بينما لم يعد الإصدار V1 متوفراً في الحزم الحالية. لذلك فإن ظهور docker-compose: command not found على خادم Ubuntu جديد اعتباراً من July 2026 أمر متوقع، وليس دليلاً على وجود عطل. تحقّق باستخدام docker compose version. إذا لم يطبع الأمر شيئاً، فثبّت الحزمة docker-compose-plugin.

تُشغَّل كل الأوامر أدناه من الدليل الذي يحتوي على compose.yaml، لأن Compose يستمد اسم المشروع من ذلك الدليل ويبحث عن الملف نسبةً إليه. إذا شغّلت الأمر نفسه من الدليل الأعلى بمستوى واحد، يتوقف Compose مع no configuration file provided: not found. إذا كان تنسيق الملف جديداً عليك، فابدأ بـأول ملف Compose على VPS ثم عد إلى هنا لمعرفة الأوامر.

دورة الحياة: الأوامر الأربعة التي تكتبها، والأمر الذي يزيل الحاويات

docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose down

ينشئ up -d الشبكة والحاويات، ويبدأ تشغيلها، ثم يعيد التحكم. ويعيد التحكم بمجرد أن تكون الحاويات منشأة، ولذلك يفشل غالباً نص نشر يتبعه باستعلام curl في المحاولة الأولى. يحجب up -d --wait التنفيذ حتى تُبلغ كل خدمة تعرّف healthcheck بأنها سليمة، ويخرج بحالة غير صفرية إذا لم تصل إحداها إلى هذه الحالة. ولا يكون هذا الخيار فعالاً إلا بقدر جودة الفحص الذي يعتمد عليه، لذلك اكتب healthcheck يمكن لـCompose الوثوق به قبل الاعتماد عليه في الأتمتة.

يوقف stop الحاويات ويحتفظ بها، لذلك يعيد start تشغيل الحاويات نفسها مع طبقة الكتابة نفسها. أما down فيوقف الحاويات ثم يزيلها ويزيل شبكة المشروع. يزول معها كل ما كُتب داخل الحاوية وخارج volume. هذا أكثر سوء فهم مكلف في Compose، وتشرح الفروق الكاملة بين down وstop المواضع التي تظهر فيها آثاره.

ليس restart إعادة تحميل. فهو يوقف الحاوية نفسها ثم يبدأ تشغيلها بالإعدادات الموجودة فيها، ولذلك لا يؤثر على الإطلاق تغيير متغير بيئة، أو وسم image جديد، أو تعديل ربط منفذ. لتطبيق تغيير في الملف، شغّل up -d مرة أخرى. يقارن Compose كل خدمة بالحاوية قيد التشغيل، ويعيد إنشاء الحاويات التي تغيّر إعدادها فقط.

تطبيق تغيير: إعادة الإنشاء أو السحب أو إعادة البناء

docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build web

لا يفعل up -d شيئاً عند عدم حدوث أي تغيير، وهذا ما يجعله آمناً للتشغيل بشكل متكرر. يتجاوز --force-recreate هذه المقارنة ويستبدل كل حاوية حتى عندما يكون الإعداد مطابقاً، ولذلك فهو أسرع طريقة لمسح الحالة غير المعتادة داخل الحاوية.

يتطلب تحديث image تشغيل أمرين لأن كل أمر يؤدي وظيفة مختلفة. ينزّل pull أحدث image لكل tag مذكور في الملف. ثم يكتشف up -d أن معرّف image الخاص بالخدمة لم يعد مطابقاً للحاوية قيد التشغيل، فيعيد إنشاءها. إذا تخطيت عملية السحب، فسيُبقي up -d إصدار latest من الشهر الماضي قيد التشغيل من دون إظهار خطأ. يظهر الخطر المقابل في stack متعدد الخدمات، حيث يمكن أن يؤدي سحب latest لكل خدمة دفعة واحدة إلى تعطيل تطبيق كان يعمل قبل عشر ثوانٍ، ولذلك يثبّت مساحة عمل AFFiNE مستضافة ذاتياً كل tag من tags الصور الأربعة بدلاً من ذلك.

ينطبق build على الخدمات التي تعرّف قسماً باسم build: بدلاً من image:. ينفّذ up -d --build عملية البناء والتشغيل في خطوة واحدة، وهذا هو المسار المعتاد أثناء تعديل الشيفرة. استخدم --no-cache فقط عندما تكون إحدى الطبقات المخزنة مؤقتاً قديمة بوضوح، لأنه يعيد بناء كل طبقة من الصفر.

معرفة ما يعمل

docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose ls

يسرد ps الحاويات قيد التشغيل فقط. تكون الخدمة التي تعطّلت أثناء البدء غير ظاهرة هناك إلى أن تضيف -a، لذلك فإن غياب حاوية من ps مع ظهورها في ps -a على أنها Exited (1) هو الشكل المعتاد لفشل بدء التشغيل. اقرأ رمز الخروج، ثم اقرأ السجلات.

يتابع logs -f كل خدمة في الوقت نفسه، ويضيف اسم الخدمة إلى بداية كل سطر. هذه هي العرضة المناسبة عندما تتواصل الخدمات مع بعضها ويكون ترتيب الأحداث مهماً. اذكر اسم خدمة لتضييق النطاق. يصبح --tail=100 مهماً عندما تكون الحاوية قيد التشغيل منذ شهر، لأن الإعداد الافتراضي يطبع السجل الكامل ويغمر الطرفية. يجيب --since 15m عن السؤال الذي تحتاج عادةً إلى إجابته: ماذا حدث أثناء إعادة التشغيل التي أجريتها للتو؟

يسرد top العمليات داخل كل حاوية، ويفصل بين «الحاوية قيد التشغيل» و«العملية داخلها قيد التشغيل». ينتقل ls خارج الدليل الحالي ويسرد كل مشاريع Compose على المضيف مع حالتها، حتى تتمكن من العثور على الحزمة التي شغّلتها قبل ثلاثة أشهر.

الحصول على shell داخل خدمة

docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web sh

ينفّذ exec أمراً داخل حاوية قيد التشغيل. ويبدأ run حاوية جديدة من تعريف الخدمة نفسه. تحتاج إلى ذلك عندما لا تبقى الخدمة قيد التشغيل مدة كافية لتنفيذ أمر داخلها. استخدم run دائماً مع --rm، لأن كل استدعاء بدونه يترك حاوية متوقفة. وتتراكم هذه الحاويات حتى يصبح docker compose ps -a غير قابل للقراءة.

جرّب sh قبل bash. لا تحتوي الصور المبنية على Alpine على bash، وتكون رسالة الفشل exec: "bash": executable file not found in $PATH. تؤدي إضافة --no-deps إلى run إلى تخطي تبعيات الخدمة. ويمنع ذلك فحص إعداد سريعاً من تشغيل قاعدة البيانات بالكامل.

يُعد run --rm web env أسرع طريقة لمعرفة البيئة التي حصلت عليها الخدمة فعلياً، بعد دمج كل ملف .env وكتلة environment: ومتغير shell. عندما تكون قيمة ما غير صحيحة، يكون ترتيب الدمج هو السبب غالباً. يوضّح كيفية حل Compose لملفات البيئة والأسرار أي مصدر تكون له الأولوية.

الشبكات والمنافذ وحل الأسماء

docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networks

يضع Compose كل خدمة على شبكة واحدة للمشروع، ويكون اسم كل خدمة اسماً في DNS على هذه الشبكة. يعرض تشغيل getent hosts db داخل web عنوان IP للحاوية عندما يعمل حل الاسم، ولا يعرض شيئاً عندما لا يعمل. لذلك يجيب خلال ثانيتين عن سؤال: «هل تستطيع هذه الحاويات رؤية بعضها؟». إذا حُلَّ الاسم لكن رُفض الاتصال، فهذا يعني أن العملية داخل db مرتبطة بـ127.0.0.1 بدلاً من 0.0.0.0، ولذلك لا تقبل أي حزمة من حاوية أخرى. يشرح كيفية عمل شبكات Compose وDNS الخاص بالخدمات بقية هذا النموذج.

يعرض port web 80 عنوان المضيف والمنفذ الذي نُشر عليه منفذ الحاوية، وهذا يلغي الحاجة إلى التخمين عندما يأتي الربط من متغير. يؤدي نشر منفذ أيضاً إلى إنشاء قاعدة جدار ناري يديرها Docker بنفسه. وتأتي هذه القاعدة قبل قواعدك، لذلك قد تصبح خدمة ظننت أنها خاصة مفتوحة أمام الإنترنت. تتناول سبب تجاوز منافذ Docker المنشورة لـufw هذه الحالة. ويكون ترك هذه المنافذ غير منشورة ووضع Proxy واحد يتولى المصادقة أمام الخدمات على شبكة المشروع هو التصميم الأكثر أماناً. وهذا ما يوفّره تشغيل Authentik كطبقة تسجيل دخول موحّد.

الأحجام والبيانات

docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -v

يطبع config --volumes الأحجام المُسمّاة التي يعرّفها المشروع، بمعدل حجم واحد في كل سطر. هذه هي القائمة التي يجب نسخها احتياطياً. عندما تحتوي الأحجام على بيانات لا يمكن استبدالها، يكون أمر النسخ الاحتياطي الدقيق مهماً بقدر أهمية القائمة. لذلك يوضّح مقارنة PhotoPrism وImmich أوامر التفريغ والنسخ التي يحتاج إليها كل خادم للصور. ينسخ cp ملفاً إلى حاوية أو منها من دون فتح shell، باستخدام صيغة service:path في الجانب الذي توجد فيه الحاوية.

يزيل down -v تلك الأحجام المُسمّاة مع الحاويات. هذا هو الأمر المناسب لإزالة مكدس اختباري، لكنه غير مناسب لأي شيء يحتوي على بيانات تهمك، لأنه لا يطلب تأكيداً ولا يوفّر طريقة للتراجع. تبقى Bind mounts موجودة بعد ذلك لأنها توجد على نظام ملفات المضيف. هذا الاختلاف في نطاق التأثير أحد أسباب الاختيار المتعمد بين Bind mounts والأحجام المُسمّاة.

تنظيف يحرر مساحة على القرص دون فقدان البيانات

docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune

يحذف --remove-orphans الحاويات التابعة للمشروع التي لم تعد تظهر في الملف، وهذا يحدث تحديداً بعد إعادة تسمية خدمة. ومن دونه، تستمر تلك الحاويات في العمل وتصبح غير ظاهرة في docker compose ps.

يعرض docker system df أين استُخدمت مساحة القرص قبل حذف أي شيء، ويفصل بين الصور والحاويات ووحدات التخزين المحلية وذاكرة التخزين المؤقت لعملية البناء، مع عرض المساحة القابلة للاسترداد لكل منها. يزيل image prune -a كل صورة لا يشير إليها أي وسم، ويكون ذلك عادةً أكبر مكسب على خادم جلب عدة إصدارات من صورة كبيرة. يمسح builder prune ذاكرة التخزين المؤقت لعملية البناء، التي تنمو بهدوء على أي خادم ينشئ صوره بنفسه.

لا يؤثر أي من ذلك في وحدة تخزين مسماة. وحدهما docker volume prune وdocker compose down -v يفعلان ذلك.

التحقق من الملف قبل أن يسبب مشكلة

docker compose config --quiet
docker compose config --services
docker compose --dry-run up -d

يتحقق config --quiet من صحة الملف ولا يطبع شيئاً عند النجاح، لذلك ضعه في خطوة تسبق النشر أو في خطاف Git. يطبع config العادي الملف بعد دمج القيم والاستبدالات بالكامل. هذه هي الطريقة للتأكد من حل متغير ما، ومن تطبيق ملف التجاوز بالترتيب المتوقع. يظهر المتغير غير المعيّن كقيمة فارغة، إلى جانب التحذير The "X" variable is not set. Defaulting to a blank string.

يُعد --dry-run علامة عامة، وليس علامة لأمر فرعي، لذلك يأتي قبل up. يطبع جميع الإجراءات التي سينفذها Compose ولا يغيّر شيئاً. وهذا يستحق ثلاثين ثانية قبل تنفيذ down على حزمة مهمة.

العمل عبر الملفات وملفات التعريف والمشروعات

docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -d

تُدمج أعلام -f المتعددة بالترتيب، وتستبدل الملفات اللاحقة إعدادات الملفات السابقة مفتاحاً بمفتاح. هذه هي الطريقة القياسية للحفاظ على ملف أساسي مع ملف تجاوز صغير للإنتاج، لكن القواعد تختلف بين القوائم والخرائط؛ لذلك اقرأ كيفية دمج ملفات Compose المتعددة قبل تصحيح مشكلة غير متوقعة.

يبدأ --profile الخدمات الموسومة بملف التعريف المحدد إلى جانب الخدمات غير الموسومة، وبذلك تبقى أدوات التصحيح خارج up العادي. يحدد -p اسم المشروع، لذا يمكن تشغيل نسختين من المكدس نفسه جنباً إلى جنب، مع شبكات منفصلة وأسماء وحدات تخزين منفصلة. استعادة المكدس بعد إعادة التشغيل ليست أمراً تكتبه يدوياً، بل وحدة تنفّذ ذلك نيابةً عنك، كما هو موضح في بدء تشغيل مكدسات Compose عند الإقلاع.

FAQ

ما الذي استبدل docker-compose الذي يحتوي على واصلة؟

Compose V2، ويُستدعى باستخدام docker compose مع ترك مسافة بين الكلمتين. وهو مكوّن إضافي مضمّن في Docker Engine، ولم تعد أداة V1 المكتوبة بلغة Python تُثبّتها الحزم الحالية. إذا لم يعرض شكل الأمر الذي يحتوي على مسافة أي ناتج، فثبّت الحزمة docker-compose-plugin الخاصة بتوزيعتك. حدّث البرامج النصية القديمة لاستخدام الشكل الذي يحتوي على مسافة بدلاً من إضافة alias، لأن V2 يتضمن flags لم تكن متاحة في V1.

لماذا لا يلتقط docker compose restart التغيير الذي أجريته على الإعدادات؟

يوقف restart الحاوية الحالية ثم يشغّلها باستخدام الإعدادات التي أُنشئت بها، ولا يعيد قراءة compose.yaml مطلقاً. يتطلب أي تغيير في متغيرات البيئة أو المنافذ أو volumes أو وسم image استخدام docker compose up -d، الذي يقارن كل خدمة بالحاوية التي تشغّلها ويعيد إنشاء الحاويات المختلفة. أضف --force-recreate عندما تريد تنفيذ الاستبدال حتى إذا لم يتغير أي شيء في الملف.

كيف أُحدّث خدمة لاستخدام image أحدث؟

شغّل docker compose pull، ثم docker compose up -d. يجلب أمر pull الـimage الحالي لكل وسم في الملف، ويعيد up -d إنشاء أي خدمة لم يعد معرّف الـimage الخاص بها مطابقاً لحاويتها. يؤدي تشغيل up -d وحده إلى إعادة استخدام الـimage الموجود على القرص، ولذلك قد تبقى stack مثبتة على latest باستخدام إصدار بُني قبل أشهر من دون عرض أي خطأ.

ما أوامر التنظيف الآمنة على خادم يعمل؟

يزيل docker system df وdocker image prune -a وdocker builder prune الـimages وcache فقط، لذلك تستمر الخدمات قيد التشغيل في العمل ولا تتأثر named volumes. الزوج الخطر هو docker compose down -v وdocker volume prune، إذ يحذفان named volumes من دون طلب تأكيد. شغّل docker compose config --volumes أولاً لتعرف ما الذي قد يتعرض للحذف.

هل يمكنني تشغيل أمر واحد من دون بدء stack كاملة؟

نعم. يشغّل docker compose run --rm --no-deps web sh حاوية واحدة من تعريف الخدمة web، ويتجاوز تبعياتها، ويحذف الحاوية عند الخروج. استخدم exec بدلاً منه عندما تكون الحاوية قيد التشغيل، لأن exec يتصل بالعملية الحية ويعرض الحالة الفعلية للخدمة.