डॉकर सीएमडी के निर्देश में कई कमांड


39

यह समझ में नहीं आ रहा है कि जब मैं `डॉकरीफाइल में सीएमडी के निर्देश के माध्यम से रनटाइम पर दो कमांड निष्पादित करने का प्रयास करता हूं। मैंने मान लिया कि यह काम करना चाहिए:

CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]

लेकिन यह काम नहीं कर रहा है। कंटेनर शुरू नहीं हुआ है। इसलिए मुझे इसे इस तरह करना पड़ा:

CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]

मुझे समझ नहीं आ रहा है। ऐसा क्यों है? पहली पंक्ति सही तरीका क्यों नहीं है? किसी ने मुझे इन "CMD खोल प्रारूप बनाम JSON प्रारूप, आदि" सामान समझा सकते हैं। सरल शब्दों में।

बस ध्यान दें - जैसा कि अपेक्षित command:था docker-compose.yml, निर्देश में था ।

जवाबों:


33

मेरा मानना ​​है कि अंतर के साथ करना पड़ सकता है, दूसरा कमांड शेल प्रसंस्करण करता है, जबकि पहला नहीं करता है। आधिकारिक दस्तावेज के अनुसार , फॉर्म execऔर shellफॉर्म है, आपकी पहली कमांड एक निष्पादन फॉर्म है और यह उदाहरण के लिए पर्यावरण चर का विस्तार नहीं करता है, जबकि दूसरा करता है। इसलिए यह संभव है कि निष्पादन फॉर्म का उपयोग करके, शेल प्रसंस्करण पर निर्भरता के कारण कमांड विफल हो सकती है। आप इसे चलाकर चेक कर सकते हैंdocker logs CONTAINERID

आपका दूसरा कमांड, शेल फॉर्म, के बराबर है -

CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm

प्रलेखन के कुछ अंश -

नोट: शेल फॉर्म के विपरीत, निष्पादन फॉर्म कमांड शेल को लागू नहीं करता है। इसका मतलब यह है कि सामान्य शेल प्रसंस्करण नहीं होता है। उदाहरण के लिए, CMD [ "echo", "$HOME" ]पर चर प्रतिस्थापन नहीं करेंगे $HOME। यदि आप शेल प्रोसेसिंग चाहते हैं तो या तो शेल फॉर्म का उपयोग करें या किसी शेल को सीधे निष्पादित करें, उदाहरण के लिए CMD [ "sh", "-c", "echo", "$HOME" ]:।


संभवतः पर्यावरण चर के कारण कमांड विफल हो गई। क्या मुझे अभी भी इस execफॉर्म का उपयोग करना चाहिए , क्योंकि यह पसंदीदा फॉर्म है? इसे क्यों पसंद किया जाता है? या मुझे सरल shellरूप का उपयोग करना चाहिए ?
व्लादन

यह विफल रहा क्योंकि एक के बाद एक कमांड निष्पादित करना एक शेल फ़ंक्शन है। पर्यावरण चर एक लाल हेरिंग है।
ब्रायन

यदि आप डॉकर में कई सेवाएं चला रहे हैं, तो मैं पर्यवेक्षक जैसे प्रक्रिया प्रबंधक का उपयोग करने की सलाह दूंगा। इस तरह आप सीएमडी अनुभाग के तहत केवल पर्यवेक्षक को लॉन्च करते हैं और यह सेवाओं को शुरू करने का ध्यान रखेगा। आप यहाँ विवरणों के लिए जाँच कर सकते हैं - docs.docker.com/articles/using_supervisord
डैनियल टी।

यह एक सटीक लेख है जिसे मैं अभी पढ़ रहा था :) धन्यवाद।
व्लाडन

मुझे अभी भी समझ नहीं आ रहा है कि आपको करने की आवश्यकता क्यों है CMD [ "sh", "-c", "echo", "$HOME"]। क्यों CMD ["sh", "-c", "echo $HOME"]या नहीं , उस बात के लिए CMD ["sh -c echo $HOME"],?
साठ

4

इसे अपने आप पर कठोर मत बनाओ। बस एक बैश फ़ाइल बनाएँ "start.sh":

#!/bin/bash

/usr/bin/command2 param1
/usr/bin/commnad1

अपने डॉकरफाइल में करें:

ADD start.sh /

CMD ["/start.sh"]

2

की json वाक्य रचना CMD(और RUNऔर ENTRYPOINT) एक कार्यकारी syscall के रूप में सीधे कर्नेल में तर्क गुजरती हैं। निष्पादन स्थल में कमांड, अलगाव, उद्धरणों से बचना, IO पुनर्निर्देशन, परिवर्तनशील प्रतिस्थापन, कमांड के बीच पाइपिंग, कई कमांड चलाना, आदि। Syscall केवल निष्पादन योग्य को चलाने के लिए ले जाता है और उस निष्पादन योग्य को पास करने के लिए तर्कों की सूची बनाता है, और इसे चलाता है।

वर्ण $चर का विस्तार करना, ;कमांड को अलग करना, (स्पेस) को अलग-अलग तर्क देना, &&और ||चेन कमांड को, >आउटपुट पुनर्निर्देशन के लिए, |कमांड के बीच पाइप करना, इत्यादि, शेल की सभी विशेषताएं हैं और उन्हें व्याख्या /bin/shया /bin/bashकार्यान्वित करने के लिए कुछ की आवश्यकता होती है ।


यदि आप स्ट्रिंग सिंटैक्स पर जाते हैं CMD, तो docker आपके कमांड को शेल के साथ चलाएगा:

CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm

अन्यथा, आपका दूसरा सिंटैक्स ठीक यही काम करता है:

CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]

ध्यान दें कि मैं कंटेनर के अंदर इस तरह से कई कमांड चलाने की सलाह नहीं देता हूं क्योंकि अगर आपका पहला कमांड विफल हो जाता है, तो कोई त्रुटि से निपटने में मदद नहीं करता है, खासकर अगर यह पृष्ठभूमि में चलता है। आप कंटेनर के अंदर पीड 1 के रूप में चल रहे एक शेल को भी छोड़ते हैं जो सिग्नल हैंडलिंग को तोड़ देगा, जिसके परिणामस्वरूप आपके कंटेनर में 10 सेकंड की देरी और अपमानजनक हत्या होगी। शेल execकमांड का उपयोग करके सिग्नल की हैंडलिंग को कम किया जा सकता है :

CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm

हालाँकि, पृष्ठभूमि में चुपचाप विफल होने वाली प्रक्रियाओं से निपटने के लिए आपको किसी तरह के मल्टी-प्रोसेस मैनेजर की तरह स्विच करने की आवश्यकता होती है, जैसे कि पर्यवेक्षक या अपने आवेदन को कई कंटेनरों में तोड़ना और उन्हें कुछ बनाने वाले जैसे कुछ के साथ तैनात करना।


1

मुझे लगता है कि पहले कमांड विफल रहता है क्योंकि डॉकर सीएमडी फॉर्म में, केवल पहला पैरामीटर निष्पादित होता है, बाकी को इस कमांड में खिलाया जाता है।

दूसरा रूप काम करता है क्योंकि सभी कमांड ";" के साथ अलग हो जाते हैं श कमांड में खिलाया जाता है, जो उन्हें निष्पादित करता है।


1

मुझे नहीं लगता कि आपको "शुरुआत" के बाद अर्ध अल्पविराम लगाना चाहिए

के बजाय का उपयोग करने का

CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]

प्रयत्न

CMD ["/etc/init.d/nullmailer", "start", "/usr/sbin/php5-fpm"]

जैसा कि docker "sh -c" का उपयोग करता है, उपरोक्त कमांड को नीचे की तरह निष्पादित किया जाएगा

/etc/init.d/nullmailer start
/etc/init.d/nullmailer /usr/sbin/php5-fpm

Json सिंटैक्स एक शेल के साथ कमांड नहीं चलाता है, sh -cउस परिदृश्य में नहीं है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.