Docker Compose commands: सर्वर मैनेजमेंट के लिए गाइड
Docker Compose V2 के लिए उपयोगी कमांड्स की सूची। इसमें लाइफसाइकिल, लॉग्स, नेटवर्क और वॉल्यूम मैनेजमेंट के लिए जरूरी कमांड्स दिए गए हैं जो सर्वर पर काम को आसान बनाते हैं।
आप वास्तव में इस्तेमाल करने वाले Compose commands
Docker Compose में दर्जनों subcommands होते हैं। Server पर दैनिक काम के लिए इनमें से लगभग एक दर्जन ही उपयोग होते हैं। यह पृष्ठ उन्हें आपके काम के आधार पर समूहित करता है, प्रत्येक के लिए एक स्पष्ट कारण देता है और जब किसी command में कोई छिपी समस्या हो, तो उसके विस्तृत विवरण की ओर निर्देशित करता है।
यहां सभी उदाहरण Compose V2 या V5 का उपयोग करते हैं: docker compose जिसमें space है, पुराने docker-compose script का नहीं। दोनों Go plugins हैं; Linux पर Compose plugin को Docker Engine से अलग install किया जाता है। Ubuntu 24.04 LTS अभी भी अपने universe repository में legacy Python V1 tool को docker-compose version 1.29.2-6ubuntu1 के रूप में उपलब्ध कराता है। docker compose version से जाँच करें। यदि command उपलब्ध नहीं है, तो Docker की repository configure करें और docker-compose-plugin package install करें।
नीचे दिए गए प्रत्येक command को उस directory से चलाया जाता है जिसमें आपकी compose.yaml file होती है। Compose override न किए जाने पर उस directory के नाम को default project name के रूप में इस्तेमाल करता है। -f या COMPOSE_FILE के बिना, Compose working directory और उसकी parent directories में configuration file खोजता है। इसलिए एक level ऊपर से चलाने पर आपका stack तभी मिलेगा, जब उसकी file उस search path में मौजूद हो। यदि file format आपके लिए नया है, तो VPS पर पहली Compose file से शुरू करें और commands के लिए यहां वापस आएं।
Lifecycle: आपके द्वारा टाइप की जाने वाली चार commands और containers हटाने वाली command
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d network बनाता है, containers बनाता है, उन्हें start करता है और वापस लौट आता है। यह containers start करने के बाद, application के ready होने की प्रतीक्षा किए बिना वापस लौटता है। इसलिए इसके बाद curl probe चलाने वाली deploy script पहली कोशिश में अक्सर fail हो जाती है। up -d --wait healthcheck वाले services के healthy होने और बिना healthcheck वाले services के running होने की प्रतीक्षा करता है। कोई service unhealthy हो या --wait-timeout समाप्त हो जाए, तो यह non-zero exit देता है। यह flag उसके पीछे मौजूद check जितना ही विश्वसनीय है। इसलिए automation में इसका उपयोग करने से पहले ऐसा healthcheck लिखें जिस पर Compose भरोसा कर सके।
stop containers को halt करता है और उन्हें बनाए रखता है। इसलिए start उन्हीं containers को उसी writable layer के साथ फिर से लाता है। down containers को stop करने के बाद उन्हें और project network को remove कर देता है। Container के अंदर और volume के बाहर लिखा गया कोई भी data उनके साथ चला जाता है। Compose में यह सबसे महंगी गलतफहमियों में से एक है। down और stop के बीच का पूरा अंतर बताता है कि इसका प्रभाव कहाँ पड़ता है।
restart reload नहीं है। यह उसी container को उसकी मौजूदा configuration के साथ stop और start करता है। इसलिए बदला हुआ environment variable, नया image tag या edited port mapping लागू नहीं होती। File change लागू करने के लिए up -d फिर से चलाएँ। Compose प्रत्येक service की तुलना उसके running container से करता है और जिनकी configuration या image बदली हो, उन्हें recreate करता है।
बदलाव लागू करना: recreate, pull या rebuild
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d तब चल रहे containers का पुन: उपयोग करता है, जब उनका configuration और image अपरिवर्तित हो; image pulls और builds service की pull policy के अनुसार होते हैं। --force-recreate इस तुलना को अनदेखा करता है और configuration समान होने पर भी हर container को replace करता है। इसलिए in-container state की असामान्य स्थिति साफ करने का यह सबसे तेज तरीका है।
स्पष्ट image update प्रक्रिया में दो commands का उपयोग होता है, क्योंकि दोनों अलग-अलग काम करते हैं। pull file में दिए गए प्रत्येक tag की current image download करता है। इसके बाद up -d देखता है कि service की image ID उसके running container से मेल नहीं खाती और उसे recreate करता है। Default missing pull policy के साथ cached tags का फिर से उपयोग किया जाता है, सिवाय latest के, जिसे हमेशा pull किया जाता है। इसका उलटा जोखिम multi-service stack में दिखता है। वहाँ सभी services के लिए एक साथ latest pull करने से वह app भी टूट सकता है जो दस seconds पहले ठीक चल रहा था। इसी कारण self-hosted AFFiNE workspace application और migration image को इसके बजाय एक ही digest पर pin करने की सलाह देता है। Pinning से upgrade एक जानबूझकर किए गए tag edit में बदल जाता है, जिसके बाद वही pull और recreate प्रक्रिया चलती है। जिस stack में boot के दौरान database migration होती है, उसमें किसी भी command से पहले dump तैयार रखना चाहिए। self-hosted Chatwoot support desk हर version bump के लिए यही प्रक्रिया अपनाता है।
build उन services पर लागू होता है जिनमें build: section घोषित होता है। इसमें वे services भी शामिल हैं जो image: घोषित करती हैं। up -d --build एक ही step में build और start करता है। Code बदलते समय यही सामान्य loop है। --no-cache का उपयोग तभी करें जब cached layer स्पष्ट रूप से stale हो, क्योंकि यह हर layer को scratch से rebuild करता है। कुछ projects एक ही cloned repo से दोनों routes उपलब्ध कराते हैं। ऐसे में ये दोनों loops वैकल्पिक update paths होते हैं। self-hosted openGym workout tracker अपने pinned checkout को build करने के लिए docker compose up -d --build का उपयोग करता है, क्योंकि इसकी latest images pull करने पर उस checkout से newer release चल सकता है।
जो चल रहा है उसे देखना
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 lsps केवल चल रहे containers की सूची दिखाता है। Start के दौरान crash हुई service तब तक दिखाई नहीं देती, जब तक आप -a न जोड़ें। इसलिए ps में container का न दिखना, जबकि ps -a उसे Exited (1) के रूप में दिखाता है, startup failure का सामान्य संकेत है। पहले exit code पढ़ें। फिर logs पढ़ें।
logs -f सभी services को एक साथ follow करता है और हर line के आगे service name जोड़ता है। जब services एक-दूसरे से communicate करती हैं और events का क्रम महत्वपूर्ण होता है, तब यही view उपयोगी है। सूची सीमित करने के लिए service का नाम दें। --tail=100 उस container के लिए महत्वपूर्ण है जो एक महीने से चल रहा हो, क्योंकि default पूरी history दिखाता है और terminal भर देता है। --since 15m उस प्रश्न का उत्तर देता है जो आम तौर पर आपके सामने होता है: अभी किए गए restart के दौरान क्या हुआ।
top प्रत्येक container के अंदर चल रही processes की सूची दिखाता है। इससे यह अलग करना संभव होता है कि container चल रहा है या उसके अंदर process चल रही है। ls वर्तमान directory से बाहर जाकर host पर चल रहे Compose projects की सूची और उनका status दिखाता है। रुके हुए projects शामिल करने के लिए -a जोड़ें।
Service के अंदर 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 shexec पहले से चल रहे container के अंदर command चलाता है। run उसी service definition से नया container शुरू करता है। जब service इतनी देर तक चालू नहीं रहती कि उसमें exec किया जा सके, तब यही आवश्यक होता है। हमेशा run को --rm के साथ इस्तेमाल करें। इसके बिना हर invocation एक stopped container छोड़ देता है। ऐसे containers की संख्या बढ़ती जाती है और अंततः docker compose ps -a पढ़ने योग्य नहीं रहता।
bash से पहले sh आज़माएँ। कुछ Alpine आधारित images में bash शामिल होता है। आधिकारिक PostgreSQL Alpine image भी इसका उदाहरण है। इसके अनुपस्थित होने पर failure में exec: "bash": executable file not found in $PATH दिखाई देता है। run में --no-deps जोड़ने से service की dependencies skip हो जाती हैं। इससे quick config check के दौरान पूरा database boot नहीं होता।
हर .env file, environment: block और shell variable merge होने के बाद service को वास्तव में मिला environment देखने का सबसे तेज तरीका run --rm web env है। जब कोई value गलत होती है, तो आम तौर पर इसका कारण merge order होता है। Compose env files और secrets को resolve कैसे करता है में बताया गया है कि कौन-सा source प्राथमिकता पाता है।
नेटवर्क, ports और name resolution
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksडिफ़ॉल्ट रूप से, Compose हर service को एक project network पर रखता है और हर service name उस network पर DNS name होता है। जब image में getent शामिल हो, तब web के अंदर getent hosts db चलाने से name resolution की जाँच होती है; इससे यह परीक्षण नहीं होता कि db connections स्वीकार करता है या नहीं। यदि name resolve हो जाता है लेकिन connection refused हो जाता है, तो जाँचें कि server चल रहा है और अनुरोधित address तथा port पर listening कर रहा है; केवल 127.0.0.1 पर bind होना इसका एक संभावित कारण है। यही सीमा बताती है कि project के बाहर शुरू किए गए container को, चाहे वह docker run से शुरू किया गया हो या अपने stack के रूप में, jellyfin जैसे service name को resolve करने के लिए shared network की आवश्यकता होती है। जब आपका Jellyfin library के लिए Halcyon front end उस server तक नहीं पहुँच पाता जिसे वह target करता है, तो सबसे पहले यही जाँच करें। इस model का बाकी भाग Compose networks और service DNS कैसे काम करते हैं में दिया गया है।
port web 80 वह host address और port दिखाता है जिस पर किसी container का port publish किया गया है। इससे तब अनुमान लगाने की जरूरत नहीं रहती जब mapping किसी variable से आई हो। किसी port को publish करने पर Docker स्वयं managed firewall rule भी लिखता है। यह rule आपके rules से पहले लागू होता है। इसलिए जिस service को आपने private माना था, वह internet पर खुली हो सकती है। इस स्थिति को published Docker ports ufw को bypass क्यों करते हैं में समझाया गया है। इन ports को unpublished छोड़ना और services के सामने project network पर एक authenticating proxy रखना अधिक सुरक्षित तरीका है। Authentik को single sign-on layer के रूप में चलाना यही व्यवस्था देता है।
Volumes और डेटा
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes project में घोषित named volumes को प्रति पंक्ति एक volume के रूप में दिखाता है। यह सूची backup inventory का केवल एक हिस्सा है: bind mounts और configuration files की भी जाँच करनी होती है। जब volumes में ऐसा डेटा हो जिसे दोबारा बनाया नहीं जा सकता, तो exact backup command उतनी ही महत्वपूर्ण होती है जितनी volumes की सूची। इसी कारण PhotoPrism और Immich की तुलना में प्रत्येक photo server के लिए dump और copy commands स्पष्ट रूप से दी गई हैं। cp shell खोले बिना किसी file को container में copy करता है या container से बाहर निकालता है। इसमें service:path form का उपयोग किया जाता है, और container वाली side पर यही form रखा जाता है।
down -v external volumes को छोड़कर declared named volumes को हटाता है। यह containers से जुड़े anonymous volumes को भी containers के साथ हटा देता है। Test stack को पूरी तरह हटाने के लिए यह सही command है, लेकिन ऐसे किसी भी stack के लिए गलत है जिसमें आपका महत्वपूर्ण डेटा हो, क्योंकि इसमें confirmation नहीं माँगा जाता और undo का विकल्प नहीं होता। Bind mounts इससे प्रभावित नहीं होते, क्योंकि वे host filesystem पर रहते हैं। Blast radius में यह अंतर bind mounts और named volumes के बीच सोच-समझकर चुनाव करने का एक कारण है।
डेटा खोए बिना disk खाली करने वाली सफाई
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans उन containers को delete करता है जो project से संबंधित हैं, लेकिन अब file में दिखाई नहीं देते। Service का नाम बदलने के बाद यही स्थिति बनती है। इसके बिना वे containers चलते रहते हैं, और docker compose ps में running orphans डिफ़ॉल्ट रूप से शामिल होते हैं।
कुछ भी delete करने से पहले docker system df दिखाता है कि disk space कहाँ उपयोग हुआ है। यह images, containers, local volumes और build cache को अलग-अलग दिखाता है और प्रत्येक के लिए reclaimable space भी बताता है। image prune -a उन सभी images को remove करता है जिन्हें कोई container उपयोग नहीं करता, चाहे वे tagged हों या नहीं। जिस box ने किसी बड़ी image के कई versions pull किए हों, वहाँ आम तौर पर इससे सबसे अधिक space खाली होता है। builder prune डिफ़ॉल्ट रूप से dangling build cache remove करता है; सभी unused build cache को remove करने के लिए -a जोड़ें।
इनमें से कोई भी named volume को नहीं छूता। docker volume prune --all, docker compose down -v और docker volume rm named volumes को remove करते हैं। सामान्य docker volume prune केवल anonymous volumes को remove करता है।
किसी भी खराबी से पहले फाइल की जांच करना
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet सफल होने पर कुछ भी प्रिंट नहीं करता है, इसलिए इसे pre-deploy चरण या git hook में इस्तेमाल करना चाहिए। साधारण config पूरी तरह से मर्ज और इंटरपोलेट की गई फाइल को प्रिंट करता है, जिससे आप यह पुष्टि कर सकते हैं कि कोई variable सही ढंग से resolve हुआ है और override फाइल आपकी अपेक्षा के अनुसार लागू हुई है। यदि कोई variable unset है, तो वह वहां खाली मान के रूप में दिखाई देगा, जिसके साथ The "X" variable is not set. Defaulting to a blank string. चेतावनी भी होगी।
--dry-run एक global flag है, न कि subcommand flag, इसलिए इसे up से पहले रखा जाता है। यह उन सभी क्रियाओं को प्रिंट करता है जो Compose करेगा और किसी भी चीज में बदलाव नहीं करता है। किसी महत्वपूर्ण stack पर down चलाने से पहले इसमें बिताए गए 30 सेकंड का समय सार्थक होता है।
फ़ाइलों, profiles और projects के साथ काम करना
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dकई -f flags क्रम से merge होते हैं, और बाद वाली files पहले वाली files को key के आधार पर override करती हैं। एक छोटी production override के साथ एक base file रखने के लिए यही standard तरीका है। हालांकि lists और maps के लिए rules अलग होते हैं, इसलिए किसी unexpected result की troubleshooting करने से पहले Compose कई files को कैसे merge करता है पढ़ें।
--profile उस profile से tagged services को untagged services के साथ start करता है। इससे debug tooling सामान्य up से अलग रहती है। -p project name set करता है, इसलिए एक ही stack की दो copies अलग networks और अलग volume names के साथ साथ चल सकती हैं। Reboot के बाद stack को वापस लाने के लिए restart policy या ऐसी unit का उपयोग करें जो आपके लिए Compose चलाती हो। इसका विवरण boot पर Compose stacks start करना में दिया गया है।
FAQ
हाइफ़न वाले docker-compose की जगह क्या आया?
Compose V2 और V5 आए, जिन्हें space के साथ docker compose के रूप में चलाया जाता है। Linux पर Compose अलग से install किया जाने वाला plugin है; Ubuntu 24.04 LTS अभी भी अपने universe repository में V1 Python tool उपलब्ध कराता है। यदि space वाला रूप उपलब्ध नहीं है, तो Docker का repository सेट अप करें और docker-compose-plugin package install करें। पुराने scripts में alias जोड़ने के बजाय उन्हें space वाले रूप में update करें, क्योंकि V2 में ऐसे flags हैं जो V1 में नहीं थे।
docker compose restart मेरे config change को क्यों नहीं अपना रहा है?
restart मौजूदा container को उसी configuration के साथ stop और start करता है, जिसके साथ वह बनाया गया था। यह compose.yaml को दोबारा पढ़ता ही नहीं है। Environment variables, ports, volumes या image tag में किसी भी बदलाव के लिए docker compose up -d आवश्यक है। यह प्रत्येक service की तुलना उसके running container से करता है और जिनमें अंतर होता है, उन्हें दोबारा बनाता है। जब file में कुछ भी न बदला हो, तब भी replacement कराना हो तो --force-recreate जोड़ें।
किसी service को नई image में कैसे update करूँ?
पहले docker compose pull चलाएँ और उसके बाद docker compose up -d चलाएँ। Pull command file में दिए गए प्रत्येक tag की current image लाता है। up -d ऐसी service को दोबारा बनाता है, जिसकी image ID उसके container से match नहीं करती। केवल up -d चलाने पर pull policy लागू होती है। Default missing policy cached images का दोबारा उपयोग करती है, सिवाय latest के, जिसे हमेशा pull किया जाता है।
Live server पर कौन-से cleanup commands सुरक्षित हैं?
docker system df बिना कुछ delete किए disk usage दिखाता है। docker image prune -a और docker builder prune unused images और build cache हटाते हैं, इसलिए चल रही services काम करती रहती हैं और named volumes पर कोई प्रभाव नहीं पड़ता। खतरनाक commands docker compose down -v और docker volume prune --all हैं। docker compose down -v project में घोषित non-external named volumes और attached anonymous volumes को बिना prompt के delete करता है। docker volume prune --all unused local volumes, जिनमें named volumes भी शामिल हैं, को एक single y/N prompt के बाद delete करता है; -f के साथ कोई prompt नहीं दिखता। पहले docker compose config --volumes चलाएँ, ताकि आपको पता हो कि क्या जोखिम में है।
क्या मैं पूरा stack शुरू किए बिना एक command चला सकता हूँ?
हाँ। docker compose run --rm --no-deps web sh web service definition से एक single container शुरू करता है, उसकी dependencies को skip करता है और आपके बाहर निकलने पर container को remove कर देता है। जब container पहले से running हो, तब exec का उपयोग करें। exec आपकी command को live container के अंदर चलाता है और वह state दिखाता है जिसमें service वास्तव में चल रही है।