أوامر متعددة في التوجيه كمد عامل الميناء

عدم فهم ما يحدث عندما أحاول تنفيذ أمرين في وقت التشغيل عبر توجيه سمد في `دوكيرفيل. افترضت أن هذا يجب أن يعمل:

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" ].

لا تجعل الأمر صعبا على نفسك. مجرد إنشاء ملف باش & مثل; بداية. ش & مثل;:

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

في دوكيرفيل الخاص بك القيام به:

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

بناء جملة جسون من CMDRUN و 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