Docker Compose: الفرق بين down وstop وحذف البيانات
تعرّف على الفرق بين stop وdown: الأول يبقي الحاويات، والثاني يحذفها وشبكة المشروع. لا تُحذف وحدة التخزين المُسمّاة إلا مع --volumes، فاحمِ بياناتك.
الإجابة المختصرة
يوقف docker compose stop الحاويات ويتركها على القرص. ويوقف docker compose down الحاويات ثم يحذفها ويحذف الشبكة التي أنشأها Compose للمشروع. لا يمس أي من الأمرين وحدة تخزين مُسمّاة. لا تُحذف قاعدة بياناتك إلا عند إضافة -v، كما في docker compose down -v، إذ يزيل ذلك وحدات التخزين المُسمّاة المُعرَّفة في قسم volumes من ملف Compose.
هذا هو الفرق الكامل في فقرة واحدة. يثبت باقي هذا الدليل ذلك باستخدام وحدة تخزين Postgres يمكنك مراقبتها وهي تبقى بعد تنفيذ down وتختفي عند تنفيذ down -v، كما يشرح الحالتين اللتين تحتاج فيهما إلى --force-recreate.
إيقاف docker compose: تبقى الحاويات موجودة
يرسل stop الإشارة SIGTERM إلى العملية الرئيسية في كل حاوية، ثم ينتظر، وبعد ذلك يرسل SIGKILL إذا كانت العملية لا تزال قيد التشغيل. مدة الانتظار الافتراضية هي 10 ثوانٍ، ويغيّرها -t. لا يتم حذف أي شيء. تحتفظ الحاوية بمعرّفها، وطبقتها القابلة للكتابة، وحجز عنوان IP الخاص بها، وسجلاتها.
docker compose stop
docker compose ps -aيعرض docker compose ps بمفرده الحاويات قيد التشغيل فقط، لذلك يطبع بعد stop جدولًا فارغًا، ويظن المستخدمون أن الحاويات اختفت. يتضمن ps -a الحاويات المتوقفة أيضًا، وهناك سترى Exited (0) بجانب كل خدمة. أعد تشغيلها باستخدام docker compose start، الذي يعيد استخدام الحاويات نفسها تمامًا.
بما أن الحاويات لا تزال موجودة، فإن كل ما كُتب داخلها خارج وحدة تخزين يظل موجودًا. يشمل ذلك حزمة ثبّتها يدويًا باستخدام 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 أو تمرّر -p. تصبح كل التغييرات التي أجريتها داخل طبقة الكتابة في الحاوية غير قابلة للاسترداد. لذلك تعامل مع down على أنه أمر يتخلص من الحاوية ويحافظ فقط على البيانات التي وضعتها في وحدات التخزين.
إذا شغّلته من الدليل الخطأ، تحصل على no configuration file provided: not found. لا يعرف Compose المشروع الذي تقصده، لذلك يرفض التنفيذ. استخدم docker compose -f /srv/myapp/compose.yaml down عندما لا تكون في مجلد المشروع.
هل يحذف docker compose down وحدات التخزين الخاصة بي؟
لا. تظل وحدة التخزين المسماة المعلنة ضمن مفتاح volumes في المستوى الأعلى موجودة بعد down، كما تظل موجودة بعد حذف الحاوية التي كانت مرفقة بها. هذا هو القلق الأكثر شيوعًا بشأن الأمر، والإجابة ثابتة في Compose v2.
أنشئ مكدسًا يمكنك اختباره. ضع ما يلي في 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، إضافةً إلى وحدات التخزين المجهولة المرتبطة بالحاويات. شغّله على المكدس نفسه.
docker compose down -v
docker volume lsلم يعد voltest_pgdata مدرجًا. شغّل المكدس مجددًا، وسيجد مدخل Postgres دليل بيانات فارغًا، لذلك يهيّئ عنقودًا جديدًا. يوضح سجل الحاوية ذلك صراحةً.
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.ظهور هذه الكتلة في مكدس يعمل منذ أشهر يعني أن وحدة التخزين أُزيلت. اختفى جدول marker، والطريقة الوحيدة لاستعادته هي استخدام نسخة احتياطية.
لا يزيل -v بعض أنواع التخزين مطلقًا. نقطة الربط هي مسار على المضيف، لذلك لا يفعل Docker سوى إلغاء تركيبها، وتبقى ملفاتك في مكانها. وحدة التخزين المعلّمة external: true مُعلنة على أنها تتبع شيئًا خارج هذا المشروع، ولا يزيلها Compose مطلقًا. أما وحدة التخزين المُسمّاة التي حذفتها من ملف Compose قبل تشغيل down -v فلم تعد مُعلنة، لذلك لا يعرف Compose أنه يجب إزالتها، وتبقى كعنصر يتيم لمدة docker volume prune.
تتسبب الحالة الأخيرة في مشكلات أثناء إعادة هيكلة المشروع. احذف خدمة ووحدة التخزين الخاصة بها من الملف، ثم شغّل down -v، وستبقى وحدة التخزين لأن الملف لم يعد يشير إليها. شغّل down -v قبل تعديل الملف، وليس بعده.
متى تحتاج فعليًا إلى --force-recreate
docker compose up -d لا يعيد إنشاء كل شيء في كل مرة. يخزّن Compose تجزئةً للإعداد المحلَّل لكل خدمة على الحاوية في صورة وسم. إذا تطابقت التجزئة وتطابق معرّف الصورة، تُترك الحاوية كما هي، وتحصل على Container voltest-db-1 Running بدلًا من Recreated. هذا هو السلوك المطلوب في معظم الحالات، لأنه يجعل تشغيل up -d بشكل متكرر آمنًا.
ولهذا السبب أيضًا قد تبدو بعض التعديلات وكأنها لم تفعل شيئًا. يحسب Compose تجزئة لتعريف الخدمة المحلَّل، وليس لمحتويات الملفات التي يشير إليها ذلك التعريف. إذا كان ملف إعداد موصولًا بالحاوية وتتم قراءته مرة واحدة عند بدء التشغيل، فلن يؤدي تعديله إلى إعادة إنشاء الحاوية، لأن مسار الربط لم يتغير. تستمر الخدمة في العمل بالقيم التي قرأتها عند الإقلاع.
docker compose up -d --force-recreateيوقف ذلك كل حاوية ويزيلها، ثم ينشئ حاوية جديدة من التعريف نفسه. استخدمه بعد تعديل ملف إعداد موصول، وكذلك عندما تنحرف حاوية إلى حالة لا يمكنك تفسيرها. لا تتأثر وحدات التخزين، لذلك تبقى قاعدة البيانات بعد إعادة الإنشاء بالقوة. لاستخدام صورة أحدث تحمل الوسم نفسه، تحتاج أيضًا إلى تنفيذ السحب.
docker compose pull
docker compose up -dيجلب pull معرّف الصورة الجديد، ثم يلاحظ up -d اختلاف معرّف الصورة عن الحاوية قيد التشغيل ويعيد إنشاءها تلقائيًا. تؤدي إضافة --force-recreate من دون pull إلى إنشاء حاوية جديدة من الصورة القديمة نفسها. لذلك يشيع قول: «أعدت الإنشاء بالقوة، وما زالت النسخة قديمة».
لا ينفّذ docker compose restart أيًا من ذلك. فهو يعيد تشغيل الحاويات الحالية ولا يعيد قراءة ملف Compose على الإطلاق، لذلك لن يُطبَّق تغيير متغير البيئة أو تغيير تعيين المنفذ. إذا عدّلت الملف، فاستخدم up -d.
النموذج الذهني الذي يجب الاحتفاظ به
الحاويات قابلة للاستبدال. الحاوية عملية مع طبقة قابلة للكتابة، ويمكن لـ Compose إنشاء حاوية مطابقة لها من الملف خلال نحو ثانية واحدة. أما وحدات التخزين فليست قابلة للاستبدال، لأنها تحتوي على النسخة الوحيدة من الحالة التي لا يستطيع أي ملف في مستودعك إعادة إنشائها.
يتوافق كل أمر من أوامر Compose مع هذا الفصل. يحافظ stop وstart على الحاوية. يستبدل down وup الحاوية ويحافظان على وحدة التخزين. down -v هو الأمر الروتيني الوحيد الذي يزيل الحالة، ولذلك يتطلب علامة صريحة. قبل كتابته على أي نظام حقيقي، تأكد من أن لديك نسخة احتياطية سبق أن استعدتها مرة واحدة على الأقل.
ينطبق المنطق نفسه على الأسرار. لا تُقرأ كلمة المرور التي تُعيَّن عبر POSTGRES_PASSWORD إلا عند تهيئة قاعدة البيانات للمرة الأولى، ولذلك فإن تغييرها في ملف البيئة وتشغيل up -d يمنحك password authentication failed for user "postgres". الحاوية جديدة، ووحدة التخزين قديمة، وما زالت وحدة التخزين القديمة تحتوي على كلمة المرور القديمة. يوضح كيفية حل Compose لملفات البيئة والأسرار أي طبقة لها الأولوية عند تعيين المتغير نفسه مرتين.
حالات الفشل والرسائل التي ستظهر
تعني no configuration file provided: not found أن Compose يعمل في دليل لا يحتوي على compose.yaml ولا docker-compose.yml. مرّر -f مع المسار الكامل.
تعني network voltest_default has active endpoints على down أن حاوية خارج هذا المشروع متصلة بشبكة المشروع، وعادةً تكون حاوية شُغّلت يدويًا باستخدام docker run --network. أزل تلك الحاوية، ثم شغّل down مرة أخرى.
تظهر Found orphan containers ([voltest-old-1]) for this project بعد إعادة تسمية خدمة أو حذفها. ما زالت الحاوية القديمة تحمل وسم المشروع. يزيلها 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 قاعدة بياناتي؟
لا، إذا كانت قاعدة البيانات موجودة في وحدة تخزين مُسمّاة أو في ربط مجلد. يزيل down الحاويات وشبكة المشروع، وتبقى وحدة التخزين على القرص مع بياناتها سليمة. عند تشغيل docker compose up -d لاحقًا، يربط حاوية جديدة بوحدة التخزين نفسها، وتبقى البيانات متاحة. يزيل 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 الحاويات، وشبكة المشروع، ووحدات التخزين المُسمّاة المعلنة في الملف، والصور التي استخدمتها الخدمات، وأي حاوية ما زالت تحمل اسم المشروع. ولا يؤثر في عمليات ربط المجلدات أو وحدات التخزين المعلَّمة بالوسم external: true. تحقّق مما ستفقده قبل تشغيل الأمر باستخدام docker volume ls.
لماذا تتجاهل حاويتي التغيير الذي أجريته في ملف إعدادات موصول؟
يقرر Compose ما إذا كان سيعيد إنشاء الحاوية بمقارنة تجزئة لتعريف الخدمة المحلَّل، ولا تتضمن هذه التجزئة محتويات الملف الموصول. لم يتغير المسار، لذلك يُبقي Compose الحاوية قيد التشغيل بالقيم التي قرأتها عند بدء التشغيل. شغّل docker compose up -d --force-recreate لإنشاء حاوية جديدة تقرأ الملف مرة أخرى.
لماذا لا تعمل قيمة POSTGRES_PASSWORD الجديدة بعد تغييرها؟
تقرأ صورة Postgres قيمة POSTGRES_PASSWORD فقط عند تهيئة دليل بيانات فارغ. تحتوي وحدة التخزين لديك بالفعل على مجموعة بيانات مهيَّأة، لذلك يُتجاهل المتغير وتظل كلمة المرور القديمة سارية. سترى password authentication failed for user "postgres". غيّر كلمة المرور باستخدام ALTER USER داخل قاعدة البيانات قيد التشغيل، أو اقبل فقدان البيانات وابدأ من جديد باستخدام docker compose down -v.