Docker Compose down أم stop: ما الفرق؟
يحافظ stop على الحاويات وطبقاتها، بينما يحذف down الحاويات والشبكة وطبقات الكتابة. لا يحذف أي منهما volume مُسمّى إلا مع الخيار volumes.
الإجابة المختصرة
يوقف docker compose stop الحاويات ويتركها على القرص. أما docker compose down فيوقف الحاويات، ثم يحذفها ويحذف الشبكة التي أنشأها Compose للمشروع. لا يؤثر أي من الأمرين في volume مُسمّى. تؤدي إضافة -v، كما في docker compose down -v، إلى إزالة الـvolumes المسماة غير الخارجية المعلنة في القسم volumes من ملف Compose والتابعة لهذا المشروع. ما يتخلص منه down فعلياً هو كل ما كتبته الحاوية في طبقة الكتابة الخاصة بها، خارج أي volume.
هذا هو الفرق كاملاً في فقرة واحدة. يثبت باقي هذا الدليل ذلك باستخدام volume لـPostgres يمكنك مراقبة بقائه بعد تنفيذ down واختفائه عند تنفيذ down -v، كما يشرح الحالتين اللتين تحتاج فيهما إلى --force-recreate.
docker compose stop: تبقى الحاويات موجودة
يرسل stop إشارة الإيقاف المهيّأة للحاوية، وهي SIGTERM افتراضياً، إلى العملية الرئيسية في كل حاوية، ثم ينتظر، ويرسل SIGKILL إذا كانت العملية لا تزال قيد التشغيل. مدة الانتظار الافتراضية هي 10 ثوانٍ، ويغيّرها -t. لا يُحذف أي شيء. تحتفظ الحاوية بمعرّفها، وطبقتها القابلة للكتابة، وسجلاتها.
docker compose stop
docker compose ps -aيعرض docker compose ps بمفرده الحاويات قيد التشغيل فقط، لذلك يطبع بعد stop جدولاً فارغاً، ويظن المستخدمون أن الحاويات اختفت. يشمل ps -a الحاويات المتوقفة، وهناك سترى الحالة Exited بجانب كل خدمة، مع رمز الخروج الذي أعادته عمليتها. يظهر Exited (0) غالباً عند الإيقاف السليم، لكن ليس دائماً. تنهي بعض الخوادم عملية الإيقاف المنظم، ثم تعيد رفع إشارة الإيقاف، فتنتهي العملية بسبب تلك الإشارة. يفعل Uvicorn ذلك تحديداً، لذلك قد يترك الإيقاف المنظم رمزاً غير صفري. وقد يعني الرمز غير الصفري أيضاً أن العملية فشلت أو قُتلت بعد انتهاء المهلة. أعد تشغيلها باستخدام docker compose start، الذي يعيد استخدام الحاويات نفسها تماماً.
بما أن الحاويات لا تزال موجودة، فإن كل ما كُتب داخلها خارج volume لا يزال موجوداً. يشمل ذلك حزمة ثبّتها يدوياً باستخدام docker compose exec، وملف إعداد عدّلته داخل الحاوية. لهذا السبب العملي يُفضّل استخدام stop أثناء تصحيح الأخطاء: إذ يمكنك إعادة التشغيل بالحالة نفسها.
docker compose down: إزالة الحاويات والشبكات
يوقف down الحاويات ثم يزيلها، إلى جانب الشبكة الافتراضية التي أنشأها Compose للمشروع. تصف وثائق Docker هذا الأمر بأنه يوقف الحاويات ويزيل الحاويات والشبكات ووحدات التخزين والصور التي أنشأها up، لكن إزالة وحدات التخزين والصور لا تحدث إلا عند طلبها باستخدام -v و--rmi.
docker compose down
docker compose ps -a
docker network lsبعد down، لا يطبع ps -a أي شيء للمشروع، وتختفي شبكة <project>_default. يأتي اسم المشروع من اسم دليل المشروع، ما لم تعيّن name: في ملف Compose، أو تعيّن COMPOSE_PROJECT_NAME، أو تمرّر -p. تصبح كل التغييرات التي أجريتها داخل طبقة الكتابة في الحاوية غير قابلة للاسترداد الآن، لذلك تعامل مع down على أنه أمر يتخلص من الحاوية ويحتفظ بالبيانات التي وضعتها في وحدات التخزين.
إذا تعذر على Compose العثور على ملف إعداد في الدليل الحالي أو في أحد الأدلة الأصلية، ولم تقدّم ملفاً عبر -f أو COMPOSE_FILE، فستحصل على no configuration file provided: not found. لا يعرف Compose أي مشروع تقصد، لذلك يرفض التنفيذ. استخدم docker compose -f /srv/myapp/compose.yaml down عندما لا تكون في مجلد المشروع.
هل يحذف docker compose down وحدات التخزين لدي؟
لا. تبقى وحدة التخزين المسماة المعلنة ضمن مفتاح المستوى الأعلى volumes بعد تنفيذ down، كما تبقى بعد حذف الحاوية التي كانت متصلة بها. هذا هو القلق الأكثر شيوعاً بشأن الأمر. غيّر Compose v5.7.0 سلوك down -v: فهو يتخطى الآن وحدات التخزين المسماة التابعة لمشروع آخر أو التي أُنشئت خارج Compose، مع عرض تحذير.
أنشئ مكدساً يمكنك اختباره. ضع المحتوى التالي في compose.yaml داخل مجلد فارغ اسمه voltest.
services:
db:
image: postgres:16.4
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:شغّله واكتب صفاً يمكنك التعرّف إليه لاحقاً.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"احذف الحاوية الآن وتحقق من وحدة التخزين.
docker compose down
docker volume lsما زال الناتج يعرض voltest_pgdata. اختفت الحاوية، لكن البيانات لم تختفِ. شغّل المكدس مجدداً واقرأ الصف.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"ستحصل على صف واحد يتضمن survived. الحاوية الجديدة حاوية مختلفة ذات معرّف مختلف، لكنها متصلة بوحدة التخزين نفسها. إذا أردت الصورة الأشمل، يشرح دليل أساسيات Compose وحدات التخزين المسماة مقارنةً بعمليات الربط، ومكان وجود كل منها فعلياً على المضيف.
ما الذي يدمّره down -v تحديداً
يزيل -v (الصيغة الطويلة --volumes) وحدات التخزين المسماة غير الخارجية المعلنة في قسم volumes من ملف Compose والتابعة لهذا المشروع، بالإضافة إلى وحدات التخزين المجهولة المرتبطة بالحاويات. في Compose v5.7.0، يتخطى وحدة التخزين المسماة التي تحمل وسم ملكية لمشروع آخر أو لا تحمل وسم مشروع، مع إصدار تحذير؛ وإذا تعذّر فحص ملكيتها، يفشل الأمر ويحافظ على وحدة التخزين. شغّله على المكدس نفسه.
docker compose down -v
docker volume lsلم يعد voltest_pgdata مدرجاً. ابدأ المكدس مرة أخرى، وسيجد entrypoint الخاص بـPostgres دليلاً فارغاً للبيانات، ثم يهيّئ عنقوداً جديداً. يوضح سجل الحاوية ذلك بعبارات صريحة.
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.إذا ظهر هذا المقطع في مكدس يعمل منذ أشهر، فهذا يعني أن Postgres يهيّئ دليلاً فارغاً للبيانات. لقد اختفى جدول marker، والطريقة الوحيدة لاستعادته هي من نسخة احتياطية.
لا تُزال بعض وحدات التخزين أبداً بواسطة -v. نقطة الربط bind mount هي مسار على المضيف، لذلك لا يفعل Docker سوى إلغاء ربطها، وتبقى ملفاتك في أماكنها. وحدة التخزين التي تحمل الوسم external: true معلنة على أنها تابعة لشيء خارج هذا المشروع، ولا يزيلها Compose أبداً. أما وحدة التخزين المسماة التي حذفتها من ملف Compose قبل تشغيل down -v فلم تعد معلنة، لذلك لا يعرف Compose أنه يجب إزالتها، وتبقى كعنصر يتيم من أجل docker volume prune -a بعد ألا تعود أي حاوية تشير إليها.
تتسبب الحالة الأخيرة في مشكلات أثناء إعادة الهيكلة. أزل خدمة ووحدة التخزين الخاصة بها من الملف، ثم شغّل down -v، فستبقى وحدة التخزين لأن الملف لم يعد يذكرها. شغّل down -v قبل تعديل الملف، لا بعده.
متى تحتاج فعلياً إلى --force-recreate
لا يعيد docker compose up -d إنشاء كل شيء في كل مرة. يخزّن Compose تجزئة لإعدادات كل خدمة بعد حلّها في الحاوية على شكل label. في Compose v5.7.0، يترك Compose الحاوية قيد التشغيل دون تغيير عندما تتطابق تجزئة الإعدادات ومعرّف الصورة وملخص image-volume، وتكون اتصالات الشبكة المتوقعة وعمليات تركيب named volume موجودة، ولا تجري إعادة إنشاء أي حاوية أصل تشارك namespace أو volume. تحصل عندئذٍ على Container voltest-db-1 Running بدلاً من Recreated. وهذا هو السلوك المطلوب في معظم الحالات، لأنه يجعل up -d آمناً للتنفيذ بشكل متكرر.
ولهذا السبب أيضاً قد تبدو بعض التعديلات بلا تأثير. يحسب Compose تجزئة لتعريف الخدمة بعد حلّه، وليس لمحتويات الملفات التي يشير إليها هذا التعريف. إذا كان ملف إعدادات مركّباً داخل الحاوية وتتم قراءته مرة واحدة عند بدء التشغيل، فلن يؤدي تعديل الملف إلى إعادة إنشاء الحاوية، لأن مسار التركيب لم يتغير. تواصل الخدمة عملها بالقيم التي قرأتها عند الإقلاع.
docker compose up -d --force-recreateيوقف هذا الأمر كل حاوية ويزيلها، ثم ينشئ حاوية جديدة من التعريف نفسه. استخدمه بعد تعديل ملف إعدادات مركّب، وكذلك عندما تنحرف حاوية إلى حالة لا يمكنك تفسيرها. لا تتأثر الـvolumes، لذلك تبقى قاعدة البيانات بعد إعادة الإنشاء القسرية. وللحصول على صورة أحدث تحمل الوسم نفسه، تحتاج أيضاً إلى pull.
docker compose pull
docker compose up -dيجلب pull معرّف الصورة الجديد، ثم يلاحظ up -d أن معرّف الصورة يختلف عن معرّف الحاوية قيد التشغيل، فيعيد إنشاء الحاوية تلقائياً. تؤدي إضافة --force-recreate من دون pull إلى إنشاء حاوية جديدة من الصورة القديمة نفسها. لذلك تُعد عبارة «أعدت الإنشاء قسراً وما زالت النسخة قديمة» شكوى شائعة جداً.
لا يفعل docker compose restart أياً من ذلك. فهو يعيد تشغيل الحاويات الموجودة من دون تطبيق التغييرات على إعداداتها، ولذلك لن يُطبَّق تغيير متغير بيئة أو تعيين منفذ. إذا عدّلت الملف، فاستخدم up -d.
النموذج الذهني الذي ينبغي الاحتفاظ به
الحاويات قابلة للاستبدال. الحاوية هي عملية مع طبقة قابلة للكتابة رقيقة، ويمكن لـCompose إنشاء حاوية بديلة من الملف والصورة. أما وحدات التخزين فليست قابلة للاستبدال، لأنها تحتوي على النسخة الوحيدة من الحالة التي لا يمكن لأي ملف في مستودعك إعادة إنشائها.
يتوافق كل أمر من أوامر Compose مع هذا الفصل. يحافظ stop وstart على الحاوية. يستبدل down وup الحاوية، مع الحفاظ على وحدة التخزين. أما down -v فهو الأمر الاعتيادي الوحيد الذي يزيل الحالة، ولذلك يحتاج إلى flag صريح. قبل كتابته على أي نظام حقيقي، تأكد من أن لديك نسخة احتياطية استعدتها مرة واحدة على الأقل.
ينطبق المنطق نفسه على الأسرار. تُستخدم كلمة المرور التي تُحدَّد عبر POSTGRES_PASSWORD لتعيين كلمة مرور قاعدة البيانات عند تهيئتها للمرة الأولى فقط، ولذلك فإن تغييرها في ملف البيئة وتشغيل up -d لا يغيّر كلمة المرور المخزنة. الحاوية جديدة، ووحدة التخزين قديمة، وما زالت وحدة التخزين القديمة تحتوي على كلمة المرور القديمة. يشرح كيفية حل Compose لملفات البيئة والأسرار أي طبقة لها الأولوية عند تعيين المتغير نفسه مرتين.
أنماط الفشل والنصوص التي ستظهر لك
no configuration file provided: not found يعني أن Compose لم يعثر على ملف إعدادات من خلال البحث في الدليل الحالي والأدلة الأصلية، وهو -f أو COMPOSE_FILE. مرّر -f مع المسار الكامل.
يشير Network voltest_default Resource is still in use في down ضمن Compose v5.7.0 إلى أن الحاويات لا تزال متصلة بشبكة المشروع، وعادةً ما تكون حاويات خارج هذا المشروع شُغّلت يدوياً باستخدام docker run --network. أزل تلك الحاويات، ثم شغّل down مرة أخرى.
يظهر Found orphan containers (voltest-old-1) for this project بعد إعادة تسمية خدمة أو حذفها. تعرض الإصدارات الحالية من Compose الأسماء مجردةً ومفصولةً بفواصل. تطبع إصدارات Compose v2 الأقدم التحذير نفسه مع الأسماء بين قوسين مربعين، كما في ([voltest-old-1]). لا تزال الحاوية القديمة تحمل وسم المشروع. يزيل docker compose down --remove-orphans هذه الحاويات.
يعني Error response from daemon: remove voltest_pgdata: volume is in use عند تنفيذ docker volume rm يدوياً أن حاويةً ما لا تزال تشير إلى وحدة التخزين، بما في ذلك الحاويات المتوقفة. شغّل docker compose down أولاً، ثم أزل وحدة التخزين، أو استخدم down -v مباشرةً. في مشروع أكبر، يوضّح مكدس Compose متعدد الخدمات عدد وحدات التخزين التي يمكن أن يراكمها مشروع واحد.
FAQ
هل يحذف docker compose down قاعدة بياناتي؟
ليس إذا كانت قاعدة البيانات موجودة في named volume أو bind mount. يزيل down الحاويات وشبكة المشروع، ويبقى الـvolume على القرص مع بياناته سليمة. يربط docker compose up -d التالي حاوية جديدة بالـvolume نفسه، وتبقى البيانات موجودة. يزيل docker compose down -v وحدات التخزين المسماة غير الخارجية المعلنة في قسم volumes من ملف Compose والتي تخص هذا المشروع.
ما الفرق بين stop وdown لحاوية أريد استخدامها مجدداً؟
يُبقي stop الحاوية، لذلك يعيدك docker compose start إلى الحاوية نفسها مع طبقة الكتابة نفسها. يبقى كل ما ثبّتَّه أو عدّلته يدوياً داخل الحاوية موجوداً. يحذف down الحاوية، لذلك ينشئ up -d التالي حاوية جديدة من الصورة، وتُفقد تلك التغييرات اليدوية. أثناء تصحيح الأخطاء، استخدم stop.
كيف أزيل كل ما أنشأه مشروع Compose؟
يزيل docker compose down -v --rmi all --remove-orphans الحاويات، وشبكة المشروع، ووحدات التخزين المسماة غير الخارجية المعلنة في الملف والتي تخص هذا المشروع، والصور التي استخدمتها الخدمات، والحاويات اليتيمة التابعة للمشروع. ولا يؤثر في bind mounts أو وحدات التخزين المعلّمة بـ external: true. تحقّق مما ستفقده قبل التنفيذ باستخدام docker volume ls.
لماذا تتجاهل حاويتي التغيير الذي أجريته على ملف إعداد موصول؟
يقرر Compose ما إذا كان سيعيد إنشاء الحاوية بمقارنة تجزئة لتعريف الخدمة بعد حله، ولا تتضمن هذه التجزئة محتويات ملف موصول. لم يتغير المسار، لذلك يُبقي Compose الحاوية قيد التشغيل بالقيم التي قرأتها عند بدء التشغيل. شغّل docker compose up -d --force-recreate لإنشاء حاوية جديدة تقرأ الملف مرة أخرى.
لماذا لا تعمل قيمة POSTGRES_PASSWORD الجديدة بعد تغييرها؟
تستخدم صورة Postgres المتغير POSTGRES_PASSWORD لتعيين كلمة مرور قاعدة البيانات فقط عند تهيئة دليل بيانات فارغ. يحتوي الـvolume لديك بالفعل على عنقود مهيّأ، لذلك يُتجاهل المتغير وتظل كلمة المرور القديمة سارية. يؤدي الاتصال باستخدام كلمة المرور الجديدة إلى password authentication failed for user "postgres". غيّر كلمة المرور باستخدام ALTER USER داخل قاعدة البيانات قيد التشغيل، أو اقبل فقدان البيانات وابدأ من جديد باستخدام docker compose down -v.