دليل أوامر Docker Compose للخوادم الحقيقية
تعلّم أوامر Compose اليومية بحسب المهمة: التشغيل، تطبيق التغييرات، السجلات، الطرفية، الشبكات، وحدات التخزين والتنظيف الآمن، مع تنبيه Compose V2.
أوامر 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 التنفيذ حتى تُبلغ كل خدمة تعرّف فحص سلامة عن حالتها السليمة، ويخرج بقيمة غير صفرية إذا لم تصل إحدى الخدمات إلى هذه الحالة. تعتمد فاعلية الخيار على الفحص الذي يقف وراءه، لذا اكتب فحص سلامة يمكن لـ Compose الوثوق به قبل الاعتماد عليه في التشغيل الآلي.
يوقف stop الحاويات ويُبقيها، ولذلك يعيد start تشغيل الحاويات نفسها مع طبقة الكتابة نفسها. يوقف down الحاويات ثم يزيلها ويزيل شبكة المشروع. تُفقد معها كل البيانات المكتوبة داخل الحاوية وخارج وحدة تخزين. هذا أكثر سوء فهم مكلف في Compose، وتوضح الفروق الكاملة بين down وstop المواضع التي يسبب فيها ذلك مشكلات.
ليس restart إعادة تحميل. فهو يوقف الحاوية نفسها ثم يبدأ تشغيلها بالإعدادات الموجودة فيها، ولذلك لا يؤثر على الإطلاق تغيير متغير بيئة أو وسم صورة جديد أو تعديل تعيين منفذ. لتطبيق تغيير الملف، شغّل 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 هذه المقارنة ويستبدل كل حاوية حتى عندما يكون الإعداد متطابقًا، ولذلك فهو أسرع طريقة لمسح الحالة غير المعتادة داخل الحاوية.
يتطلب تحديث صورة أمرين لأن لكل منهما وظيفة مختلفة. ينزّل pull الصورة الحالية لكل وسم مذكور في الملف. ثم يكتشف up -d أن معرّف صورة الخدمة لم يعد يطابق الحاوية قيد التشغيل، فيعيد إنشاءها. إذا تخطيت السحب، فسيُبقي up -d إصدار latest من الشهر الماضي قيد التشغيل من دون خطأ.
ينطبق 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 حاوية جديدة من تعريف الخدمة نفسه. تحتاج إلى ذلك عندما لا تبقى الخدمة قيد التشغيل مدة كافية لاستخدام exec داخلها. استخدم 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 لملفات env والأسرار أي مصدر له الأولوية.
الشبكات والمنافذ وحل الأسماء
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 هذه الحالة.
وحدات التخزين والبيانات
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vيعرض config --volumes وحدات التخزين المُسمّاة التي يعرّفها المشروع، واحدة في كل سطر. هذه هي القائمة التي يجب نسخها احتياطيًا. ينسخ cp ملفًا إلى حاوية أو منها من دون فتح shell، باستخدام صيغة service:path في الجانب الذي توجد فيه الحاوية.
يزيل down -v وحدات التخزين المُسمّاة تلك مع الحاويات. هذا هو الأمر المناسب لإزالة مكدس اختباري، وغير المناسب لأي شيء يحتوي على بيانات تهمك، لأنه لا يطلب تأكيدًا ولا يوفّر طريقة للتراجع. تبقى عمليات الربط 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 hook. يطبع 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، ولم تعد الحزم الحالية تثبّت أداة Python الخاصة بـ V1. إذا لم يطبع الشكل الذي يحتوي على مسافة أي شيء، فثبّت الحزمة docker-compose-plugin الخاصة بتوزيعتك. حدّث البرامج النصية القديمة لاستخدام الشكل الذي يحتوي على مسافة بدلًا من إضافة اسم مستعار، لأن V2 يوفّر خيارات لم تكن موجودة في V1.
لماذا لا يلتقط docker compose restart التغيير الذي أجريته على الإعدادات؟
يوقف restart الحاوية الموجودة ثم يشغّلها باستخدام الإعدادات التي أُنشئت بها، ولا يعيد قراءة compose.yaml مطلقًا. يتطلب أي تغيير في متغيرات البيئة أو المنافذ أو وحدات التخزين أو وسم الصورة استخدام docker compose up -d، الذي يقارن كل خدمة بالحاوية قيد التشغيل ثم يعيد إنشاء الحاويات المختلفة. أضف --force-recreate عندما تريد تنفيذ الاستبدال حتى إذا لم يتغير أي شيء في الملف.
كيف أحدّث خدمة لاستخدام صورة أحدث؟
شغّل docker compose pull، ثم docker compose up -d. يجلب أمر السحب الصورة الحالية لكل وسم في الملف، ويعيد up -d إنشاء أي خدمة لم يعد معرّف صورتها مطابقًا لحاويتها. يؤدي تشغيل up -d وحده إلى إعادة استخدام الصورة الموجودة على القرص، ولذلك قد تظل حزمة مثبتة على latest تستخدم إصدارًا بُني منذ أشهر من دون عرض أي خطأ.
ما أوامر التنظيف الآمنة على خادم قيد التشغيل؟
يزيل docker system df وdocker image prune -a وdocker builder prune الصور وذاكرة التخزين المؤقت فقط، لذلك تواصل الخدمات قيد التشغيل عملها ولا تتأثر وحدات التخزين المسماة. الزوج الخطير هو docker compose down -v وdocker volume prune، إذ يحذفان وحدات التخزين المسماة من دون طلب تأكيد. شغّل docker compose config --volumes أولًا لمعرفة ما قد يتعرض للخطر.
هل يمكنني تشغيل أمر واحد من دون بدء الحزمة كاملة؟
نعم. يشغّل docker compose run --rm --no-deps web sh حاوية واحدة من تعريف الخدمة web، ويتجاوز تبعياتها، ويحذف الحاوية عند الخروج. استخدم exec بدلًا من ذلك عندما تكون الحاوية قيد التشغيل، لأن exec ينضم إلى العملية الحية ويعرض الحالة الفعلية للخدمة.