ถ้าเป็นไปได้ฉันมักจะรวมคำสั่งที่สร้างไฟล์ด้วยคำสั่งที่ลบไฟล์เดียวกันเหล่านั้นเป็นRUN
บรรทัดเดียว เนื่องจากแต่ละRUN
บรรทัดเพิ่มเลเยอร์ให้กับรูปภาพผลลัพธ์จึงเป็นการเปลี่ยนแปลงของระบบไฟล์ที่คุณสามารถดูได้docker diff
จากคอนเทนเนอร์ชั่วคราวที่สร้างขึ้น หากคุณลบไฟล์ที่สร้างในเลเยอร์อื่นระบบไฟล์ยูเนี่ยนทั้งหมดจะลงทะเบียนการเปลี่ยนแปลงระบบไฟล์ในเลเยอร์ใหม่ไฟล์จะยังคงอยู่ในเลเยอร์ก่อนหน้านี้และถูกจัดส่งผ่านเครือข่ายและเก็บไว้ในดิสก์ ดังนั้นหากคุณดาวน์โหลดซอร์สโค้ดแตกไฟล์คอมไพล์เป็นไบนารีแล้วลบ tgz และซอร์สไฟล์ในตอนท้ายคุณต้องการให้ทำทั้งหมดนี้ในเลเยอร์เดียวเพื่อลดขนาดภาพ
ต่อไปฉันเองแยกเลเยอร์ตามศักยภาพในการนำมาใช้ซ้ำในรูปภาพอื่น ๆ และการใช้แคชที่คาดหวัง หากฉันมีภาพ 4 ภาพทั้งหมดที่มีอิมเมจพื้นฐานเหมือนกัน (เช่นเดเบียน) ฉันอาจดึงคอลเล็กชันยูทิลิตี้ทั่วไปของรูปภาพเหล่านั้นส่วนใหญ่มาเป็นคำสั่งรันครั้งแรกเพื่อให้รูปภาพอื่น ๆ ได้รับประโยชน์จากการแคช
ลำดับใน Dockerfile มีความสำคัญเมื่อพิจารณาการนำแคชรูปภาพมาใช้ใหม่ ฉันดูส่วนประกอบใด ๆ ที่ไม่ค่อยจะอัปเดตมากนักอาจเป็นได้ก็ต่อเมื่ออัปเดตอิมเมจพื้นฐานและเพิ่มสูงขึ้นใน Dockerfile ในตอนท้ายของ Dockerfile ฉันรวมคำสั่งใด ๆ ที่จะทำงานได้อย่างรวดเร็วและอาจเปลี่ยนแปลงบ่อยเช่นการเพิ่มผู้ใช้ด้วย UID เฉพาะของโฮสต์หรือการสร้างโฟลเดอร์และการเปลี่ยนสิทธิ์ หากคอนเทนเนอร์มีโค้ดที่ตีความ (เช่น JavaScript) ที่กำลังพัฒนาอย่างแข็งขันสิ่งนั้นจะถูกเพิ่มให้ช้าที่สุดเพื่อให้การสร้างใหม่รันเฉพาะการเปลี่ยนแปลงเดียวนั้น
ในแต่ละกลุ่มของการเปลี่ยนแปลงเหล่านี้ฉันรวบรวมให้ดีที่สุดเท่าที่จะทำได้เพื่อย่อเลเยอร์ ดังนั้นหากมีโฟลเดอร์ซอร์สโค้ดที่แตกต่างกัน 4 โฟลเดอร์โฟลเดอร์เหล่านั้นจะถูกวางไว้ในโฟลเดอร์เดียวดังนั้นจึงสามารถเพิ่มได้ด้วยคำสั่งเดียว การติดตั้งแพ็กเกจใด ๆ จากบางสิ่งเช่น apt-get จะรวมอยู่ใน RUN เดียวเมื่อเป็นไปได้เพื่อลดจำนวนค่าใช้จ่ายของตัวจัดการแพ็คเกจให้เหลือน้อยที่สุด (การอัปเดตและการล้างข้อมูล)
อัปเดตสำหรับการสร้างหลายขั้นตอน:
ฉันกังวลน้อยลงมากเกี่ยวกับการลดขนาดภาพในขั้นตอนสุดท้ายของงานสร้างหลายขั้นตอน เมื่อขั้นตอนเหล่านี้ไม่ได้ติดแท็กและส่งไปยังโหนดอื่นคุณสามารถเพิ่มโอกาสในการใช้แคชซ้ำได้มากที่สุดโดยแยกแต่ละคำสั่งออกเป็นRUN
บรรทัดแยกกัน
อย่างไรก็ตามนี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบในการบีบเลเยอร์เนื่องจากสิ่งที่คุณคัดลอกระหว่างขั้นตอนทั้งหมดคือไฟล์ไม่ใช่ส่วนที่เหลือของข้อมูลเมตาของรูปภาพเช่นการตั้งค่าตัวแปรสภาพแวดล้อมจุดเข้าใช้งานและคำสั่ง และเมื่อคุณติดตั้งแพ็กเกจในการแจกจ่าย linux ไลบรารีและการอ้างอิงอื่น ๆ อาจกระจัดกระจายไปทั่วระบบไฟล์ทำให้การคัดลอกการอ้างอิงทั้งหมดทำได้ยาก
ด้วยเหตุนี้ฉันจึงใช้การสร้างแบบหลายขั้นตอนแทนการสร้างไบนารีบนเซิร์ฟเวอร์ CI / CD ดังนั้นเซิร์ฟเวอร์ CI / CD ของฉันจะต้องมีเครื่องมือในการรันdocker build
เท่านั้นและไม่มี jdk, nodejs, go และ ติดตั้งเครื่องมือคอมไพล์อื่น ๆ