एक अलग कमांड के साथ एक रोका डॉकर कंटेनर कैसे शुरू करें?


251

मैं एक अलग कमांड के साथ डॉक कंटेनर को रोकना शुरू करना चाहूंगा, क्योंकि डिफ़ॉल्ट कमांड क्रैश हो जाता है - मतलब मैं कंटेनर को शुरू नहीं कर सकता और फिर 'डॉकर्स एक्जीक्यूट' का उपयोग कर सकता हूं।

मूल रूप से मैं एक शेल शुरू करना चाहूंगा ताकि मैं कंटेनर की सामग्री का निरीक्षण कर सकूं।

सौभाग्य से मैंने -it विकल्प के साथ कंटेनर बनाया!

जवाबों:


380

अपनी रुकी हुई कंटेनर आईडी खोजें

docker ps -a

बंद कंटेनर को कमिट करें:

यह आदेश संशोधित कंटेनर स्थिति को एक नई छवि में सहेजता है user/test_image

docker commit $CONTAINER_ID user/test_image

एक अलग प्रविष्टि बिंदु के साथ प्रारंभ / चलाएं:

docker run -ti --entrypoint=sh user/test_image

एंट्रीपॉइंट तर्क विवरण: https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime

ध्यान दें:

ऊपर दिए गए चरण एक ही फाइल सिस्टम स्टेट के साथ एक रुके हुए कंटेनर को शुरू करते हैं। यह एक त्वरित जांच के लिए बहुत अच्छा है। लेकिन पर्यावरण चर, नेटवर्क कॉन्फ़िगरेशन, संलग्न वॉल्यूम और अन्य कर्मचारी विरासत में नहीं मिले हैं, आपको इन सभी तर्कों को स्पष्ट रूप से निर्दिष्ट करना चाहिए।

एक रोका कंटेनर शुरू करने के लिए कदम यहाँ से उधार लिए गए हैं: (अंतिम टिप्पणी) https://github.com/docker/docker/issues/18078


1
नहीं, चित्र केवल पढ़ने के लिए हैं। यह एक नई छवि test_image में कंटेनर राज्य संशोधित बचाता है
Dmitriusan

4
यह env, वॉल्यूम, UID,… के बारे में लगभग सभी विन्यास को याद करता है… रुके हुए कंटेनर के साथ यह सब सामान्य रूप से फाइलसिस्टम है (जो कि शायद कुछ के लिए पर्याप्त है)
फ्लोरियन क्लेन

4
यह बहुत अच्छा होगा यदि मैं किसी तरह एक ही वातावरण, नेटवर्क कॉन्फिग, संलग्न वॉल्यूम प्राप्त कर सकता हूं। क्या inspectआउटपुट को कॉन्फ़िगरेशन में परिवर्तित करना संभव है जो बाद के रन के साथ उपयोग किया जाता है?
ओथियस

2
@Webman, हाँ, लेकिन यह उन संस्करणों के लिए सही नहीं है जो कंटेनर को रोकने से पहले घुड़सवार थे। जब आप अगली बार कंटेनर शुरू करते हैं, तो आपको वही वॉल्यूम स्पष्ट रूप से संलग्न करना होगा
दिमित्रिअसन

1
@ EmreTapcı, मुझे लगता है कि ऐसा करना डॉकटर विचारधारा के खिलाफ है। आभासी मशीनों के विपरीत, कंटेनरों को एक गायन-उपयोग रन-एंड-थ्रो-दूर इकाई होने का इरादा है। आप आका 90210 उत्तर का पालन करने की कोशिश कर सकते हैं , लेकिन यह एक हैक होगा।
दिमित्रिअसन

126

इस फ़ाइल को संपादित करें (आपके रुके हुए कंटेनर के अनुरूप):

vi /var/lib/docker/containers/923...4f6/config.json

अपने नए कमांड, जैसे / बिन / बैश पर इंगित करने के लिए "पथ" पैरामीटर बदलें। आप कमांड को तर्क पास करने के लिए "आर्ग्स" पैरामीटर भी सेट कर सकते हैं।

डॉकटर सेवा को पुनः आरंभ करें (ध्यान दें कि यह सभी चालू कंटेनर बंद कर देगा):

service docker restart

अपने कंटेनरों की सूची बनाएं और सुनिश्चित करें कि कमांड बदल गई है:

docker ps -a

कंटेनर शुरू करें और इसे संलग्न करें, अब आपको अपने शेल में होना चाहिए!

docker start -ai mad_brattain

डॉकटर 1.7.1 का उपयोग करके फेडोरा 22 पर काम किया।

नोट: यदि आपका शेल संवादात्मक नहीं है (जैसे कि आपने मूल कंटेनर को -it विकल्प के साथ नहीं बनाया है), तो आप इसके बजाय "/ bin / sleep 600" या "/ bin / tail -f / dev / null" कमांड को बदल सकते हैं आपको शेल को प्राप्त करने के दूसरे तरीके के रूप में "docker exec -it CONTID / bin / bash" करने के लिए पर्याप्त समय देने के लिए।

NOTE2: doer के नए संस्करणों में config.v2.json है, जहां आपको Entrypoint या Cmd (धन्यवाद user60561) बदलने की आवश्यकता होगी।


44
मेरी आँखें। मेरी आँखें। मुझे उम्मीद है कि यह डॉकटर में इसे ठीक से संभालने के लिए कहीं न कहीं एक सुविधा का अनुरोध है।
gertvdijk

2
@AlexeyStrakh आप एक शेल प्राप्त करने के लिए "/ usr / bin / स्लीप 600" चलाने की कोशिश कर सकते हैं और फिर "docker exec -it / bin / bash" कर सकते हैं। हालांकि मुझे यकीन नहीं है कि कैसे उस पथ चर पर मापदंडों को रखा जाए। अन्यथा कोशिश करें और एक और आदेश ढूंढें जो आपको निष्पादित करने के लिए लंबे समय तक जीवित रहेगा, या दिमित्रिअसन से जवाब देखें।
आका 90210

3
इस सवाल का एकमात्र सटीक उत्तर है: अन्य सभी प्रस्ताव "लगभग समान" कंटेनर चलाते हैं, लेकिन वे वॉल्यूम, env, UIDs, ...
फ्लोरियन क्लेन

3
मेरे मामले में / usr / bin / नींद उपलब्ध नहीं थी। मेरे साथ सफलता थी..."Path":"tail","Args":["-f","/dev/null"]...
19

4
Docker के नए संस्करणों में config.v2.json, जहाँ आपको Entrypointया तो बदलने की आवश्यकता होगी Cmd
user60561

20

अपनी प्रविष्टि स्क्रिप्ट के शीर्ष पर एक चेक जोड़ें

डॉकर को वास्तव में एक नई सुविधा के रूप में इसे लागू करने की आवश्यकता है, लेकिन यहां उन स्थितियों के लिए एक और वैकल्पिक विकल्प है जिसमें आपके पास एक एंट्रीपॉइंट है जो सफलता या विफलता के बाद समाप्त हो जाता है, जिससे इसे डीबग करना मुश्किल हो सकता है।

यदि आपके पास पहले से कोई एंट्रीपॉइंट स्क्रिप्ट नहीं है, तो अपने कंटेनर के लिए जो भी कमांड (कमांड) चाहिए, उसे बनाएं। फिर, इस फ़ाइल के शीर्ष पर, इन पंक्तियों को जोड़ें entrypoint.sh:

# Run once, hold otherwise
if [ -f "already_ran" ]; then
    echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
    cat
fi
touch already_ran

# Do your main things down here

यह सुनिश्चित करने के लिए कि catकनेक्शन रखता है, आपको TTY प्रदान करने की आवश्यकता हो सकती है। मैं अपने Entrypoint स्क्रिप्ट के साथ कंटेनर चला रहा हूँ जैसे:

docker run -t --entrypoint entrypoint.sh image_name

यह स्क्रिप्ट को एक बार चलाने का कारण बनेगा, एक ऐसी फ़ाइल का निर्माण करेगा जो यह इंगित करता है कि यह पहले से ही चला गया है (कंटेनर के आभासी फाइल सिस्टम में)। आप डिबगिंग करने के लिए कंटेनर को पुनः आरंभ कर सकते हैं:

docker start container_name

जब आप कंटेनर को पुनरारंभ करते हैं, तो already_ranफ़ाइल मिल जाएगी, जिससे एंट्रीपॉइंट स्क्रिप्ट को स्टाल किया जाएगा cat(जो कि इनपुट के लिए हमेशा इंतजार करता है जो कभी नहीं आएगा, लेकिन कंटेनर को जीवित रखता है)। आप तब डिबगिंग bashसत्र निष्पादित कर सकते हैं :

docker exec -i container_name bash

जब कंटेनर चल रहा होता है, तो आप स्क्रिप्ट को फिर already_ranसे हटाने और मैन्युअल रूप से निष्पादित कर सकते हैं entrypoint.sh, यदि आपको उस तरह से डिबग करने की आवश्यकता है।


3
इसके अतिरिक्त, आप एंट्रीपॉइंट को रन /bin/shकरने के बजाय बना catसकते हैं - फिर आप हमेशा बस रीस्टार्ट हो सकते हैं। अपने समाधान चट्टानों!
डैनी दुलाई

4

मेरी समस्या:

  • मैंने एक कंटेनर शुरू किया docker run <IMAGE_NAME>
  • और फिर इस कंटेनर में कुछ फाइलें जोड़ीं
  • फिर मैंने कंटेनर को बंद कर दिया और इसे फिर से शुरू करने का प्रयास किया जैसा कि ऊपर बताया गया है।
  • लेकिन जब मैंने नई फाइलों को चेक किया तो वे गायब थीं
  • जब मैं दौड़ता docker ps -aहूं तो मुझे दो कंटेनर दिखाई देते हैं।
  • इसका मतलब है कि हर बार जब मैं docker run <IMAGE_NAME>कमांड चला रहा था , नई छवि बन रही थी

समाधान: पहली बार चलाए गए उसी कंटेनर पर काम करने के लिए, इन चरणों का पालन करें

  • docker ps अपने कंटेनर के कंटेनर पाने के लिए
  • docker container start <CONTAINER_ID> मौजूदा कंटेनर शुरू करने के लिए
  • फिर आप जहां से चले थे, उसे जारी रख सकते हैं। जैसेdocker exec -it <CONTAINER_ID> /bin/bash
  • फिर आप इसमें से एक नई छवि बनाने का निर्णय ले सकते हैं

इस सवाल का जवाब नहीं है। ओपी यह जानना चाहता है कि कंटेनर को फिर से कैसे शुरू किया जाए, लेकिन इसमें इस्तेमाल किए जाने वाले की तुलना में अलग-अलग तर्कों के साथdocker run <containerID>
CodeBlooded

2

मैंने @ दिमित्रिअसन का उत्तर लिया और इसे एक उपनाम में बदल दिया:

उर्फ docker-run-prev-कंटेनर = 'prev_container_id = "$ (docker ps -aq | head -n1)" && docker प्रतिबद्ध "$ prev_container_id" "prev_container_id" / $ prev_container_id "&& docker run -it --entrypoint = bash" " / $ prev_container_id " '

इसे अपने ~/.bashrcएलियास फ़ाइल में जोड़ें , और आपके पास एक निफ्टी नया docker-run-prev-containerउर्फ होगा जो आपको पिछले कंटेनर में एक शेल में छोड़ देगा।

डिबगिंग के लिए सहायक विफल रहा docker build


2

यह बिल्कुल वैसा नहीं है जैसा आप पूछ रहे हैं, लेकिन आप docker exportएक बंद कंटेनर पर उपयोग कर सकते हैं यदि आप चाहते हैं कि सभी फाइलों का निरीक्षण किया जाए।

mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR

1

यह निर्दिष्ट नहीं किया गया था कि कंटेनर बाहर निकल रहा है या नहीं, केवल यह कि आपका कोड क्रैश हो गया है और आपको यह देखने की आवश्यकता है कि कंटेनर में क्या चल रहा है। यदि यह बाहर नहीं निकल रहा है, तो यहां एक और संभावित समाधान है।

कंटेनर आईडी प्राप्त करें docker ps

docker exec -it 665b4a1e17b6 /bin/sh

यदि एंटेरपॉइंट कुछ समस्याग्रस्त करने के लिए सेट है, तो इसे दिमित्रिअसन के उत्तर में सुझाए गए अनुसार भी ओवरराइड किया जा सकता है। यह भी ध्यान दिया जाना चाहिए कि आप किसी भी चालू कंटेनर के साथ संलग्न कर सकते हैं docker attach। इतने सारे समाधान अलग समाधान। मुझे अभी छवि के लिए प्रतिबद्ध होने की आवश्यकता नहीं है। यह अनावश्यक लगता है।

डॉकर निष्पादन के लिए डॉक्स - https://docs.docker.com/engine/reference/commandline/exec/

डॉकर के लिए डॉक्स संलग्न करें - https://docs.docker.com/engine/reference/commandline/attach/


-12

मैं वास्तव में इन दोनों उत्तरों से असहमत हूं। यदि आप अभी देखना चाहते हैं कि कंटेनर में क्या है, तो आप शेल प्राप्त करने के लिए इस कमांड को चला सकते हैं। सभी या किसी भी विन्यास में प्रविष्टि बिंदु को बदलने की आवश्यकता नहीं है।

docker run -it <image_name> bash

12
यह काम नहीं करता है क्योंकि ऑप एक कंटेनर के बारे में पूछ रहा है, छवि नहीं।
पीटर Vrabel

मुझे लगता है कि आपका अधिकार है, लेकिन ऐसा करने का कोई कारण नहीं दिखता है। आप स्टडआउट करने के लिए लॉग लॉग कर सकते हैं और docker logs <container_id> --followआपको वह देगा जो आपको चाहिए। एक अन्य विकल्प यह है कि ऊपर दिए गए कमांड का उपयोग करें और फिर उस छवि पर दुर्घटनाग्रस्त सेवा को डॉकटरफाइल में शुरू करें और वहां से डिबग करें।
deadbabykitten

4
रन कमांड एक छवि से एक नया कंटेनर बनाता है। यह एक रोका हुआ कंटेनर शुरू नहीं करता है।
वलीद अब्दुल्ला

2
उम्म, .. क्या ऐसा नहीं है कि कर्ता की बात यह है कि हर छवि को उसी तरह से बनाया जा सकता है? यह आपके तर्क को नकार देता है। वह बंद कंटेनर शुरू करने की आवश्यकता नहीं है। कोई भी कंटेनर बिल्कुल वैसा ही है, इसलिए यह वास्तव में कोई फर्क नहीं पड़ता कि वह कौन सा शुरू या रोकता है। वह केवल सामग्री का निरीक्षण करने की कोशिश कर रहा है। सबसे आसान तरीका यह है कि कमांड और पाइप आउटपुट को कमांड को लॉग इन करें और रन करें। आप लोग कभी-कभी सरल समस्याओं के लिए सबसे जटिल समाधान के साथ आते हैं।
deadbabykitten

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.