ไวยากรณ์ JSON ของCMD(และRUNและENTRYPOINT) ผ่านการขัดแย้งเคอร์เนลโดยตรงเป็น syscall exec ไม่มีการแยกคำสั่งออกจากอาร์กิวเมนต์ด้วยช่องว่างการหลีกเลี่ยงคำพูดการเปลี่ยนเส้นทาง IO การแทนที่ตัวแปรการไพพ์ระหว่างคำสั่งการรันหลายคำสั่ง ฯลฯ ใน exec syscall syscall ใช้เวลาเรียกใช้งานเพื่อรันและรายการอาร์กิวเมนต์เพื่อส่งไปยังไฟล์เรียกใช้นั้นและรันได้
อักขระที่ต้องการ$ขยายตัวแปร;เพื่อแยกคำสั่ง(เว้นวรรค) เพื่อแยกอาร์กิวเมนต์&&และ||คำสั่งลูกโซ่>สำหรับการเปลี่ยนเส้นทางเอาต์พุตไป|ยังไพพ์ระหว่างคำสั่ง ฯลฯ เป็นคุณลักษณะทั้งหมดของเชลล์และต้องการอะไรบางอย่าง/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"]
โปรดทราบว่าฉันไม่แนะนำให้เรียกใช้หลายคำสั่งด้วยวิธีนี้ภายในคอนเทนเนอร์เนื่องจากไม่มีการจัดการข้อผิดพลาดหากคำสั่งแรกของคุณล้มเหลวโดยเฉพาะหากทำงานในพื้นหลัง นอกจากนี้คุณยังปล่อยให้เชลล์ทำงานเป็น pid 1 ภายในคอนเทนเนอร์ซึ่งจะทำลายการจัดการสัญญาณส่งผลให้เกิดความล่าช้า 10 วินาทีและฆ่าภาชนะของคุณโดยนักเทียบท่า การจัดการสัญญาณสามารถบรรเทาได้โดยใช้execคำสั่งเชลล์:
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
อย่างไรก็ตามการจัดการกระบวนการที่ล้มเหลวในเบื้องหลังอย่างเงียบ ๆ คุณต้องเปลี่ยนไปใช้ตัวจัดการหลายกระบวนการบางประเภทเช่น supervisord หรือแยกแอปพลิเคชันของคุณออกเป็นหลาย ๆ ตู้คอนเทนเนอร์
execแบบฟอร์มนี้เนื่องจากเป็นรูปแบบที่ต้องการหรือไม่ ทำไมถึงเป็นที่ต้องการ หรือฉันควรใช้shellแบบฟอร์มที่ง่ายขึ้น?