Docker Compose stop और down में क्या अंतर है?
Docker Compose stop कंटेनरों को सुरक्षित रखता है जबकि down उन्हें और नेटवर्क को हटा देता है। ध्यान दें कि दोनों ही named volumes को नहीं हटाते, इसके लिए --volumes फ्लैग जरूरी है।
संक्षिप्त उत्तर
docker compose stop कंटेनरों को रोकता है और उन्हें डिस्क पर सुरक्षित रखता है। docker compose down उन्हें रोकता है और फिर उन कंटेनरों तथा उस नेटवर्क को हटा देता है जिसे Compose ने प्रोजेक्ट के लिए बनाया था। कोई भी कमांड किसी named volume को प्रभावित नहीं करती है। यदि आप -v जोड़ते हैं, जैसा कि docker compose down -v में है, तो यह Compose फाइल के volumes सेक्शन में घोषित उन non-external named volumes को हटा देता है जो इस प्रोजेक्ट से संबंधित हैं। down जो डेटा हटाता है, वह वह सब कुछ है जिसे कंटेनर ने किसी भी वॉल्यूम के बाहर, अपनी स्वयं की writable layer में लिखा था।
एक पैराग्राफ में यही पूरा अंतर है। इस गाइड का शेष भाग इसे एक Postgres वॉल्यूम के साथ सिद्ध करता है, जिसे आप down के बाद सुरक्षित रहते हुए और down -v के अंतर्गत गायब होते हुए देख सकते हैं, और यह उन दो स्थितियों की व्याख्या करता है जहाँ आपको --force-recreate की आवश्यकता होती है।
docker compose stop: कंटेनर बने रहते हैं
stop प्रत्येक कंटेनर की मुख्य प्रक्रिया (main process) को उसका कॉन्फ़िगर किया गया स्टॉप सिग्नल भेजता है, जो डिफ़ॉल्ट रूप से SIGTERM होता है। यह प्रतीक्षा करता है और यदि प्रक्रिया अभी भी चल रही हो, तो SIGKILL भेजता है। डिफ़ॉल्ट प्रतीक्षा समय 10 सेकंड है और -t इसे बदल देता है। कुछ भी डिलीट नहीं होता है। कंटेनर अपनी ID, अपनी राइटेबल लेयर और अपने लॉग्स को बनाए रखता है।
docker compose stop
docker compose ps -adocker compose ps अकेले चलाने पर केवल चल रहे कंटेनर्स को दिखाता है, इसलिए stop के बाद यह एक खाली टेबल प्रिंट करता है और लोगों को लगता है कि कंटेनर गायब हो गए हैं। ps -a में रुके हुए कंटेनर भी शामिल होते हैं, और वहीं आपको प्रत्येक सर्विस के बगल में Exited स्टेटस दिखाई देगा, साथ ही वह एग्जिट कोड भी जो उसकी प्रक्रिया ने दिया था। एक क्लीन शटडाउन अक्सर Exited (0) दिखाता है, लेकिन हमेशा नहीं। कुछ सर्वर ग्रेसफुल शटडाउन पूरा करने के बाद स्टॉप सिग्नल को फिर से रेज़ (re-raise) करते हैं ताकि प्रक्रिया उस सिग्नल से समाप्त हो, और Uvicorn बिल्कुल ऐसा ही करता है, इसलिए एक व्यवस्थित स्टॉप भी नॉन-जीरो कोड छोड़ सकता है। नॉन-जीरो कोड का मतलब यह भी हो सकता है कि प्रक्रिया विफल हो गई या टाइमआउट के बाद उसे मार दिया गया। उन्हें docker compose start के साथ वापस लाएं, जो बिल्कुल उन्हीं कंटेनर्स का पुन: उपयोग करता है।
चूंकि कंटेनर अभी भी मौजूद हैं, इसलिए वॉल्यूम के बाहर उनके अंदर लिखी गई कोई भी चीज़ वहीं रहती है। इसमें वह पैकेज भी शामिल है जिसे आपने docker compose exec के साथ मैन्युअल रूप से इंस्टॉल किया था, और वह कॉन्फ़िग फ़ाइल जिसे आपने कंटेनर के अंदर एडिट किया था। डिबगिंग के दौरान stop को प्राथमिकता देने का यही व्यावहारिक कारण है: आप उसी स्थिति में रीस्टार्ट कर सकते हैं।
docker compose down: containers और networks हटाना
down containers को रोकता है और फिर उन्हें हटा देता है, साथ ही उस default network को भी हटा देता है जिसे Compose ने project के लिए बनाया था। Docker documentation इसे containers को रोकने और up द्वारा बनाई गई containers, networks, volumes और images को हटाने के रूप में वर्णित करता है, लेकिन volumes और images वाला हिस्सा केवल तभी होता है जब आप -v और --rmi के साथ ऐसा करने का निर्देश देते हैं।
docker compose down
docker compose ps -a
docker network lsdown के बाद, ps -a project के लिए कुछ भी print नहीं करता है और <project>_default network हट चुका होता है। Project का नाम project directory के नाम से लिया जाता है, जब तक कि आप Compose file में name: सेट न करें, COMPOSE_PROJECT_NAME सेट न करें, या -p पास न करें। container की writable layer के अंदर किए गए आपके सभी बदलाव अब recover नहीं किए जा सकते, इसलिए down को एक ऐसे command के रूप में देखें जो container को हटा देता है और केवल वही data सुरक्षित रखता है जिसे आपने volumes में रखा है।
यदि Compose को current directory या उसके parent directories में configuration file नहीं मिलती है, और आपने -f या COMPOSE_FILE के माध्यम से कोई file प्रदान नहीं की है, तो आपको no configuration file provided: not found प्राप्त होगा। Compose को यह पता नहीं होता कि आपका मतलब किस project से है, इसलिए वह प्रक्रिया रोक देता है। जब आप project folder में न हों, तो docker compose -f /srv/myapp/compose.yaml down का उपयोग करें।
क्या docker compose down मेरे volumes को हटा देता है?
नहीं। टॉप लेवल volumes key के अंतर्गत घोषित किया गया named volume down से अधिक समय तक बना रहता है, और यह उस container से भी अधिक समय तक रहता है जिससे वह जुड़ा था। इस कमांड के बारे में यह सबसे आम डर है। Compose v5.7.0 ने down -v में बदलाव किया है: यह अब किसी अन्य project से संबंधित या Compose के बाहर बनाए गए named volumes को एक चेतावनी के साथ छोड़ देता है।
एक ऐसा stack सेट करें जिसका आप परीक्षण कर सकें। इसे voltest नामक एक खाली directory में compose.yaml के अंदर रखें।
services:
db:
image: postgres:16.4
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:इसे start करें और एक ऐसी row लिखें जिसे आप बाद में पहचान सकें।
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');"अब container को नष्ट करें और volume की जाँच करें।
docker compose down
docker volume lsआउटपुट में अभी भी voltest_pgdata सूचीबद्ध है। Container हट चुका है और डेटा सुरक्षित है। Stack को वापस लाएं और row को पढ़ें।
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"आपको survived वाली एक row प्राप्त होगी। नया container एक अलग container है जिसका ID अलग है, लेकिन वह उसी volume से जुड़ा है। यदि आप व्यापक जानकारी चाहते हैं, तो Compose basics guide में bind mounts के मुकाबले named volumes और host पर प्रत्येक के वास्तविक स्थान के बारे में बताया गया है।
down -v वास्तव में क्या नष्ट करता है
-v (पूर्ण रूप --volumes) Compose फाइल के volumes सेक्शन में घोषित उन non-external named volumes को हटा देता है जो इस प्रोजेक्ट से संबंधित हैं, साथ ही कंटेनरों से जुड़े anonymous volumes को भी हटा देता है। Compose v5.7.0 में, किसी अन्य प्रोजेक्ट के ओनरशिप लेबल वाले या बिना किसी प्रोजेक्ट लेबल वाले named volume को एक चेतावनी के साथ छोड़ दिया जाता है; यदि इसकी ओनरशिप की जांच नहीं की जा सकती है, तो कमांड विफल हो जाता है और वॉल्यूम को सुरक्षित रखता है। इसे उसी स्टैक पर चलाएं।
docker compose down -v
docker volume lsvoltest_pgdata अब सूचीबद्ध नहीं है। स्टैक को फिर से शुरू करें और 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 इसे कभी नहीं हटाता है। एक named volume जिसे आपने down -v चलाने से पहले Compose फाइल से हटा दिया था, वह अब घोषित नहीं है, इसलिए Compose को उसे हटाने के बारे में पता नहीं चलता है और जब कोई कंटेनर इसे रेफर नहीं करता है, तो यह docker volume prune -a के लिए एक अनाथ (orphan) के रूप में पीछे छूट जाता है।
वह अंतिम स्थिति रिफैक्टरिंग के दौरान लोगों को फंसाती है। फाइल से एक सर्विस और उसके वॉल्यूम को हटा दें, down -v चलाएं, और वॉल्यूम बच जाता है क्योंकि फाइल अब इसका उल्लेख नहीं करती है। फाइल को एडिट करने के बाद नहीं, बल्कि उससे पहले down -v चलाएं।
जब आपको वास्तव में --force-recreate की आवश्यकता होती है
docker compose up -d हर बार सब कुछ फिर से नहीं बनाता है। Compose प्रत्येक service के resolved configuration का एक hash container पर label के रूप में store करता है। Compose v5.7.0 में, जब configuration hash, image ID और image-volume digest मेल खाते हैं, उसके अपेक्षित network connections और named volume mounts मौजूद होते हैं, और कोई namespace- या volume-sharing parent फिर से नहीं बनाया जा रहा होता है, तो चल रहे container को नहीं छेड़ा जाता है। आपको Recreated के बजाय Container voltest-db-1 Running मिलता है। यह वह व्यवहार है जो आप लगभग हमेशा चाहते हैं, क्योंकि यह up -d को बार-बार चलाना सुरक्षित बनाता है।
यही कारण है कि कुछ बदलाव करने पर भी कुछ नहीं होता है। Compose resolved service definition का hash बनाता है, न कि उन files की सामग्री का जिनकी ओर वह definition इशारा करती है। container में mount की गई और startup पर एक बार पढ़ी गई config file को edit करने पर recreate ट्रिगर नहीं होगा, क्योंकि mount path नहीं बदला है। service उन values के साथ चलती रहती है जिन्हें उसने boot के समय पढ़ा था।
docker compose up -d --force-recreateयह प्रत्येक container को रोकता और हटाता है और उसी definition से एक नया container बनाता है। mounted config file में बदलाव करने के बाद, और जब कोई container ऐसी स्थिति में आ जाए जिसे आप समझा न सकें, तब इसका उपयोग करें। Volumes को नहीं छुआ जाता है, इसलिए database एक force recreate के बाद भी सुरक्षित रहता है। उसी tag पर एक नई image प्राप्त करने के लिए आपको pull की भी आवश्यकता होती है।
docker compose pull
docker compose up -dpull नई image ID को fetch करता है, और up -d फिर चल रहे container से एक अलग image ID देखता है और उसे अपने आप recreate कर देता है। pull के बिना --force-recreate जोड़ने पर आपको उसी पुरानी image से एक नया container मिलता है। यही कारण है कि "मैंने force recreate किया और यह अभी भी पुराना version है" एक आम शिकायत है।
docker compose restart इनमें से कुछ भी नहीं करता है। यह existing containers को उनके configuration में बदलाव लागू किए बिना restart करता है, इसलिए बदला हुआ environment variable या बदला हुआ port mapping लागू नहीं होगा। यदि आपने file edit की है, तो up -d का उपयोग करें।
ध्यान में रखने योग्य मानसिक मॉडल
Containers प्रतिस्थापन योग्य (replaceable) होते हैं। एक container एक process और एक पतली writable layer का संयोजन है, और Compose फाइल और image से इसका प्रतिस्थापन तैयार कर सकता है। Volumes प्रतिस्थापन योग्य नहीं होते हैं, क्योंकि इनमें state की एकमात्र प्रति (copy) होती है जिसे आपके repository की कोई भी फाइल पुनः उत्पन्न नहीं कर सकती है।
प्रत्येक Compose verb इसी विभाजन के अनुरूप कार्य करता है। stop और start container को बनाए रखते हैं। down और up container को बदल देते हैं और volume को बनाए रखते हैं। down -v एकमात्र नियमित command है जो state को हटा देती है, इसीलिए इसे एक स्पष्ट flag की आवश्यकता होती है। किसी भी वास्तविक सिस्टम पर इसे चलाने से पहले, सुनिश्चित करें कि आपके पास एक backup है जिसे आपने कम से कम एक बार restore करके देखा है।
यही तर्क secrets पर भी लागू होता है। POSTGRES_PASSWORD के माध्यम से सेट किया गया password केवल database के पहली बार initialize होने पर उसका password सेट करने के लिए उपयोग किया जाता है, इसलिए अपनी environment file में इसे बदलने और up -d चलाने से stored password में कोई बदलाव नहीं होता है। Container नया होता है और volume पुराना, और पुराने volume में अभी भी पुराना password ही रहता है। Compose कैसे env files और secrets को resolve करता है यह बताता है कि जब एक ही variable दो बार सेट किया जाता है, तो कौन सी layer प्रभावी होती है।
विफलता के प्रकार और दिखाई देने वाले संदेश
no configuration file provided: not found का अर्थ है कि Compose अपनी वर्तमान निर्देशिका और पैरेंट निर्देशिका खोज, -f, या COMPOSE_FILE के माध्यम से कॉन्फ़िगरेशन फ़ाइल नहीं ढूँढ सका। पूर्ण पथ के साथ -f का उपयोग करें।
Compose v5.7.0 में down पर Network voltest_default Resource is still in use का अर्थ है कि कंटेनर अभी भी प्रोजेक्ट नेटवर्क से जुड़े हैं, आमतौर पर वे जिन्हें docker run --network के साथ मैन्युअल रूप से शुरू किया गया था और जो इस प्रोजेक्ट का हिस्सा नहीं हैं। उन कंटेनरों को हटाएँ, फिर दोबारा down चलाएँ।
Found orphan containers (voltest-old-1) for this project तब दिखाई देता है जब आप किसी सर्विस का नाम बदलते हैं या उसे हटाते हैं। वर्तमान Compose नामों को बिना किसी विशेष चिह्न के और अल्पविराम (comma) से अलग करके सूचीबद्ध करता है। पुराने Compose v2 रिलीज़ में यही चेतावनी नामों को वर्गाकार कोष्ठक (square brackets) में प्रिंट करती है, जैसा कि ([voltest-old-1]) में है। पुराना कंटेनर अभी भी प्रोजेक्ट लेबल रखता है। docker compose down --remove-orphans उन्हें हटा देता है।
मैन्युअल docker volume rm पर Error response from daemon: remove voltest_pgdata: volume is in use का अर्थ है कि कोई कंटेनर अभी भी उस वॉल्यूम का संदर्भ ले रहा है, जिसमें रुके हुए कंटेनर भी शामिल हैं। पहले docker compose down चलाएँ, फिर वॉल्यूम हटाएँ, या बस down -v का उपयोग करें। एक बड़े प्रोजेक्ट पर, एक मल्टी-सर्विस Compose स्टैक दिखाता है कि एक प्रोजेक्ट में कितने वॉल्यूम जमा हो सकते हैं।
FAQ
क्या docker compose down मेरे डेटाबेस को डिलीट कर देता है?
नहीं, यदि डेटाबेस किसी named volume या bind mount में स्थित है। down केवल containers और project network को हटाता है, जबकि volume अपने डेटा के साथ डिस्क पर सुरक्षित रहता है। अगला docker compose up -d उसी volume से एक नया container जोड़ देता है और डेटा वहां उपलब्ध रहता है। docker compose down -v उन non-external named volumes को हटा देता है जो Compose file के volumes सेक्शन में घोषित हैं और इस प्रोजेक्ट से संबंधित हैं।
जिस container को मैं वापस चाहता हूँ, उसके लिए stop और down में क्या अंतर है?
stop container को बनाए रखता है, इसलिए docker compose start आपको उसी container पर वापस ले जाता है जिसमें वही writable layer होती है। आपने container के अंदर मैन्युअल रूप से जो कुछ भी इंस्टॉल या एडिट किया है, वह मौजूद रहता है। down container को डिलीट कर देता है, इसलिए अगला up -d इमेज से एक नया container बनाता है और वे मैन्युअल बदलाव खो जाते हैं। डिबगिंग के दौरान stop का उपयोग करें।
Compose प्रोजेक्ट द्वारा बनाई गई हर चीज़ को मैं कैसे हटाऊं?
docker compose down -v --rmi all --remove-orphans containers, project network, फाइल में घोषित non-external named volumes जो इस प्रोजेक्ट के हैं, सर्विसेज द्वारा उपयोग की गई इमेजेस और प्रोजेक्ट के लिए orphan containers को हटा देता है। यह bind mounts या external: true के रूप में चिह्नित volumes को नहीं छूता है। इसे चलाने से पहले docker volume ls के साथ जांच लें कि आप क्या खोने वाले हैं।
मेरा container माउंट की गई config फाइल में किए गए बदलाव को क्यों अनदेखा कर रहा है?
Compose यह तय करता है कि container को फिर से बनाना है या नहीं, इसके लिए वह resolved service definition के हैश की तुलना करता है, और उस हैश में माउंट की गई फाइल की सामग्री शामिल नहीं होती है। पाथ नहीं बदला है, इसलिए Compose container को उन्हीं वैल्यूज के साथ चलाता रहता है जिन्हें उसने स्टार्टअप पर पढ़ा था। फाइल को फिर से पढ़ने वाला नया container बनाने के लिए docker compose up -d --force-recreate चलाएं।
मेरा नया POSTGRES_PASSWORD बदलने के बाद काम क्यों नहीं कर रहा है?
Postgres इमेज केवल खाली डेटा डायरेक्टरी को इनिशियलाइज़ करते समय डेटाबेस पासवर्ड सेट करने के लिए POSTGRES_PASSWORD का उपयोग करती है। आपके volume में पहले से ही एक इनिशियलाइज़्ड क्लस्टर मौजूद है, इसलिए वेरिएबल को अनदेखा कर दिया जाता है और पुराना पासवर्ड ही लागू रहता है। नए पासवर्ड के साथ कनेक्ट करने पर आपको password authentication failed for user "postgres" मिलता है। चलते हुए डेटाबेस के अंदर ALTER USER के साथ पासवर्ड बदलें, या डेटा खोने के लिए तैयार होकर docker compose down -v के साथ शुरुआत से शुरू करें।