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

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

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

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

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

मैं नहीं समझता। ऐसा क्यों है? पहली पंक्ति सही तरीका क्यों नहीं है? क्या कोई मुझे ये "सीएमडी शेल प्रारूप बनाम जेसन प्रारूप, आदि" सामान समझा सकता है । सरल शब्दों में ।

बस नोट करने के लिए-वही साथ था command: में निर्देश docker-compose.yml, जैसा कि अपेक्षित था ।

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

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

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

दस्तावेज़ीकरण के अंश -

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

इसे अपने आप पर कठिन मत बनाओ । बस बनाने के लिए एक bash फ़ाइल "प्रारंभ करें । श":

#!/bin/bash/usr/bin/command2 param1/usr/bin/command1

में अपने Dockerfile करते हैं:

ADD start.sh /RUN chmod +x /start.shCMD ["/start.sh"]

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

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


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

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

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

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

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

उदाहरण के लिए, कल्पना करें कि आपके पास चलाने के लिए दो पायथन कमांड हैं python init_reset.py और python app.py. फिर सीएमडी का उपयोग करके, आप दो कमांड को सिंगल कमांड के साथ जोड़ सकते हैं

CMD python init_reset.py ; python app.py

डॉकर कंपोज़ में, यह निम्न उदाहरण के रूप में किया जा सकता है:

command: ["sh", "-c", "    apt update && apt install -y libldap-common;    cp /ca.crt /usr/local/share/ca-certificates/;    update-ca-certificates;    exec apache2-foreground  "]

exec मुख्य निष्पादन योग्य के संदर्भ को अपाचे 2-फॉरग्राउंड में बदल देगा।

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

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

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

कोशिश करो

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

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

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