ฉันสับสนเกี่ยวกับเมื่อฉันควรใช้VSCMD
RUN
ตัวอย่างเช่นในการรันคำสั่ง bash / shell (เช่นls -la
) ฉันมักจะใช้CMD
หรือมีสถานการณ์ที่ฉันจะใช้RUN
หรือไม่? พยายามทำความเข้าใจแนวปฏิบัติที่ดีที่สุดเกี่ยวกับDockerfile
คำสั่งที่คล้ายกันสองประการนี้
ฉันสับสนเกี่ยวกับเมื่อฉันควรใช้VSCMD
RUN
ตัวอย่างเช่นในการรันคำสั่ง bash / shell (เช่นls -la
) ฉันมักจะใช้CMD
หรือมีสถานการณ์ที่ฉันจะใช้RUN
หรือไม่? พยายามทำความเข้าใจแนวปฏิบัติที่ดีที่สุดเกี่ยวกับDockerfile
คำสั่งที่คล้ายกันสองประการนี้
คำตอบ:
RUNเป็นขั้นตอนการสร้างอิมเมจสถานะของคอนเทนเนอร์หลังจากRUN
คำสั่งจะถูกส่งไปยังอิมเมจคอนเทนเนอร์ Dockerfile สามารถมีหลายRUN
ขั้นตอนที่เลเยอร์อยู่ด้านบนของอีกขั้นเพื่อสร้างอิมเมจ
CMDเป็นคำสั่งที่คอนเทนเนอร์ดำเนินการตามค่าเริ่มต้นเมื่อคุณเรียกใช้อิมเมจที่สร้างขึ้น Dockerfile จะใช้เฉพาะการCMD
กำหนดขั้นสุดท้ายเท่านั้น สามารถแทนที่เมื่อเริ่มต้นภาชนะด้วยCMD
docker run $image $other_command
รายการยังเกี่ยวข้องอย่างใกล้ชิดCMD
และสามารถปรับเปลี่ยนวิธีที่ภาชนะเริ่มต้นภาพ
RUN
จำเป็นในการตั้งค่าสภาพแวดล้อมของคุณและ CMD ของคุณ (เท่านั้น) เปิดตัวกระบวนการทำงานในภาชนะของคุณตัวอย่างเช่นสำหรับ nginx แยกจากgithub.com/nginxinc/docker-nginx/blob/ …คุณเห็นบรรทัดCMD ["nginx", "-g", "daemon off;"]
RUN
- ทริกเกอร์คำสั่งในขณะที่เราสร้างภาพนักเทียบท่า
CMD
- ทริกเกอร์คำสั่งในขณะที่เราเปิดภาพนักเทียบท่าที่สร้างขึ้น
ฉันพบนี้บทความที่เป็นประโยชน์มากที่จะเข้าใจความแตกต่างระหว่างพวกเขา:
RUN - คำสั่ง RUN อนุญาตให้คุณติดตั้งแอปพลิเคชันและแพ็คเกจที่จำเป็นสำหรับมัน มันรันคำสั่งใด ๆ ที่ด้านบนของภาพปัจจุบันและสร้างเลเยอร์ใหม่โดยยอมรับผล บ่อยครั้งที่คุณจะพบคำสั่ง RUN หลายคำสั่งใน Dockerfile
CMD - คำสั่ง CMD ช่วยให้คุณสามารถตั้งค่าคำสั่งเริ่มต้นซึ่งจะดำเนินการเฉพาะเมื่อคุณเรียกใช้คอนเทนเนอร์โดยไม่ระบุคำสั่ง หากคอนเทนเนอร์ Docker รันด้วยคำสั่งคำสั่งเริ่มต้นจะถูกละเว้น หาก Dockerfile มีคำสั่ง CMD มากกว่าหนึ่งคำสั่งทั้งหมด แต่
คำสั่ง CMD สุดท้ายจะถูกละเว้น
RUN - ติดตั้ง Python ตอนนี้คอนเทนเนอร์ของคุณมี python ที่เขียนลงในรูปภาพแล้ว
CMD - python hello.py เรียกใช้สคริปต์ที่คุณชื่นชอบ
คำสั่ง RUN: โดยทั่วไปคำสั่ง RUN จะดำเนินการตามคำสั่งเริ่มต้นเมื่อเราสร้างภาพ นอกจากนี้ยังจะทำการเปลี่ยนแปลงรูปภาพในขั้นตอนต่อไป
อาจมีคำสั่ง RUN มากกว่า 1 คำสั่งเพื่อช่วยในการสร้างภาพใหม่
คำสั่ง CMD: คำสั่ง CMD จะตั้งค่าคำสั่งเริ่มต้นสำหรับคอนเทนเนอร์ใหม่ สิ่งนี้จะไม่ถูกดำเนินการในเวลาที่สร้าง
หากไฟล์นักเทียบท่ามีคำสั่งมากกว่า 1 CMD คำสั่งทั้งหมดจะถูกละเว้นยกเว้นคำสั่งสุดท้าย เนื่องจากคำสั่งนี้จะไม่ดำเนินการใด ๆ แต่เพียงตั้งค่าคำสั่งเริ่มต้น
หมายเหตุ: อย่าสับสน RUN ด้วย CMD RUN เรียกใช้คำสั่งและยอมรับผลลัพธ์ CMD ไม่ได้ดำเนินการอะไรในเวลาที่สร้าง แต่ระบุคำสั่งที่ตั้งใจไว้สำหรับภาพ
จากการอ้างอิงไฟล์นักเทียบท่า
RUN : มีได้มากมายและใช้ในกระบวนการสร้างเช่นติดตั้งหลายไลบรารี
CMD : สามารถมีเพียง 1 ซึ่งเป็นของคุณรันจุดเริ่มต้น (เช่น["npm", "start"]
, ["node", "app.js"]
)
มีการตอบเพียงพอในRUNและCMD ผมแค่อยากจะเพิ่มคำไม่กี่คำบนจุดเข้าใช้งาน อาร์กิวเมนต์CMDสามารถเขียนทับได้โดยอาร์กิวเมนต์บรรทัดคำสั่งในขณะที่อาร์กิวเมนต์ENTRYPOINTจะใช้เสมอ
บทความนี้เป็นแหล่งข้อมูลที่ดี
คำตอบที่มีอยู่ครอบคลุมส่วนใหญ่ของสิ่งที่ทุกคนต้องการดูคำถามนี้ ดังนั้นฉันจะครอบคลุมบางพื้นที่สำหรับ CMD และ RUN
GingerBeer ให้ความสำคัญ: คุณจะไม่ได้รับข้อผิดพลาดใด ๆ หากคุณใส่ CMD มากกว่าหนึ่งรายการ - แต่การทำเช่นนั้นเป็นการสิ้นเปลือง ฉันต้องการทำอย่างละเอียดด้วยตัวอย่าง:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
หากคุณสร้างสิ่งนี้ลงในภาพและเรียกใช้คอนเทนเนอร์ในภาพนี้จากนั้นเมื่อ GingerBeer ระบุเฉพาะ CMD ล่าสุดเท่านั้นที่จะได้รับการเอาใจใส่ ดังนั้นผลลัพธ์ของคอนเทนเนอร์นั้นจะเป็น:
กำลังดำเนินการ CMD 2
วิธีที่ฉันคิดคือ "CMD" ตั้งค่าตัวแปรส่วนกลางเดียวสำหรับรูปภาพทั้งหมดที่กำลังสร้างอยู่ดังนั้นคำสั่ง "CMD" ที่ต่อเนื่องจะเขียนทับตัวแปรใด ๆ ที่เขียนไปยังตัวแปรโกลบอลก่อนหน้านี้และในภาพสุดท้ายที่สร้างขึ้น คนสุดท้ายที่จะเขียนชนะ เนื่องจาก Dockerfile ดำเนินการตามลำดับจากบนลงล่างเรารู้ว่า CMD ที่อยู่ล่างสุดคืออันที่ได้รับ "เขียน" ขั้นสุดท้ายนี้ (พูดเชิงเปรียบเทียบ)
จุดที่น่าสังเกตุที่จะสังเกตเห็นเกี่ยวกับ RUN คือการใช้ฟังก์ชั่นบริสุทธิ์แม้ว่าจะมีผลข้างเคียงและถูกแคชไว้ สิ่งนี้หมายความว่าถ้า RUN มีผลข้างเคียงบางอย่างที่ไม่เปลี่ยนรูปผลลัพธ์และรูปภาพนั้นถูกแคชไว้แล้ว RUN จะไม่ถูกดำเนินการอีกครั้งดังนั้นผลข้างเคียงจะไม่เกิดขึ้นในการสร้างครั้งต่อไป ตัวอย่างเช่นใช้ Dockerfile นี้:
FROM busybox
RUN echo "Just echo while you work"
ครั้งแรกที่คุณเรียกใช้คุณจะได้รับผลลัพธ์เช่นนี้พร้อมด้วยตัวอักษรและตัวเลขที่แตกต่างกัน:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
ขอให้สังเกตว่าคำสั่ง echo ถูกดำเนินการในด้านบน ครั้งที่สองที่คุณเรียกใช้มันจะใช้แคชและคุณจะไม่เห็นเสียงสะท้อนใด ๆ ในผลลัพธ์ของบิลด์:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Using cache
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest