อิมเมจ Docker ใหญ่ เพราะมีอะไรติดมาจากตอนบิ้ว

อิมเมจ Docker ใหญ่ เพราะมีอะไรติดมาจากตอนบิ้ว - Image 1
25/12/2025•Admin Team•
TutorialHomelabDevOpsdocker

ตอนเริ่มทำ Dockerfile เราอาจใส่เครื่องมือทุกอย่างที่ใช้พัฒนาไว้ใน image เดียว เพราะต้องมีทั้งตัวติดตั้ง dependency ตัวบิ้ว และไฟล์ของโปรเจกต์ เมื่อคำสั่งสร้างผ่านแล้วก็เอา image นั้นไปรันต่อได้ทันที

แต่สิ่งที่จำเป็นตอนสร้างโปรแกรมไม่ได้จำเป็นตอนโปรแกรมทำงานเสมอไปครับ ถ้า image ที่ปล่อยยังพา source, compiler, cache และไฟล์ที่ไม่ได้ใช้ไปด้วย การเปลี่ยนแต่ละรอบก็อาจส่งของมากกว่าที่ runtime ต้องการ

ก่อนเปลี่ยน base image ให้เล็กที่สุด ลองไล่ว่าข้างในมีอะไรและแต่ละอย่างอยู่เพื่อขั้นไหน แล้วค่อยจัดเส้นทางบิ้วให้เหลือของที่งานปลายทางใช้จริง พร้อมตรวจว่าแอปยังทำหน้าที่ได้ครบหลังลดลง

เริ่มจากรายการที่ต้องใช้ตอนรัน

แอปแต่ละประเภทต้องใช้ของต่างกัน บางตัวได้ executable ที่นำไปรันต่อได้ บางตัวต้องมี runtime กับ dependency และบางตัวมีไฟล์ generated หรือข้อมูลประกอบที่ถูกสร้างระหว่างบิ้ว จึงต้องเริ่มจากวิธีแพ็กของ framework ที่ใช้อยู่จริง

ไม่ควรสรุปว่าโฟลเดอร์ที่ชื่อว่า dev ลบทิ้งได้ทั้งหมด หรือไฟล์ที่ไม่อยู่ข้างตัวแอปไม่มีผล เพราะเครื่องมือบางอย่างสร้าง runtime assets ไว้อีกที่หนึ่ง การลดควรมีรายการที่อธิบายได้ว่าไฟล์ใดจำเป็นและไปอยู่ path ใดใน image ปลายทาง

แนวคิด multi-stage build เลือกผลบิ้วและ runtime ที่ต้องใช้แทนคัดลอกเครื่องมือพัฒนาทั้งหมด ไม่ใช่ภาพวัดขนาดจริง

รวมถึง library ของระบบ ใบรับรอง และข้อมูลที่แอปใช้ระหว่างรัน หากเลือก base ที่ต่างตระกูล ก็ต้องตรวจความเข้ากันได้ของ native modules กับส่วนเชื่อมระบบ ไม่ใช้เพียงขนาดที่เล็กกว่าเป็นหลักฐานว่าแทนกันได้

การรู้รายการ runtime ยังช่วยเรื่องอัปเดตด้วย เพราะเราจะเห็นว่าส่วนใดมาจาก base image ส่วนใดมาจาก dependency ของแอป และควรตรวจรุ่นใดเมื่อมีการแก้ไข ไม่ต้องพึ่งว่าการ rebuild ด้วยชื่อเดิมจะเปลี่ยนทุกอย่างให้ตรงโดยอัตโนมัติ

multi-stage แยกพื้นที่เตรียมของกับพื้นที่ใช้งาน

Docker รองรับการมีหลาย stage ใน Dockerfile ทำให้ขั้นหนึ่งใช้ชุดเครื่องมือสำหรับบิ้ว แล้วเลือกคัดลอกผลที่ต้องใช้ไปยัง stage ปลายทางได้ ตัว builder จึงไม่จำเป็นต้องกลายเป็นสภาพเดียวกับ runtime ทั้งหมด

ประเด็นสำคัญอยู่ที่เลือกผลบิ้วอย่างชัดเจน ถ้าแยก stage แล้วท้ายที่สุดยังคัดลอกทั้งโฟลเดอร์เดิมพร้อม cache และ dependency ทุกชนิด ก็อาจยังพาของที่ไม่จำเป็นตามมาเหมือนเดิม เพียงเปลี่ยนรูปไฟล์ตั้งค่าเท่านั้น

ตรวจ artifact กับพฤติกรรม runtime และแยกตัวเลขขนาดอิมเมจ การส่งจาก registry และ build cache ออกจากกัน

เมื่อใช้ COPY --from ควรรู้ว่าอ้าง stage ใดและ path ที่ได้อยู่ในรูปแบบใด แล้วตรวจสิทธิ์เจ้าของกับตำแหน่งทำงานตอนรันด้วย เพราะไฟล์ที่ย้ายมาถูกต้องอาจยังเปิดไม่ได้ถ้า user ปลายทางไม่มีสิทธิ์อ่านหรือเขียนพื้นที่ที่ต้องใช้

การแยกขั้นทดสอบกับขั้นแพ็กก็ช่วยให้เห็นหลักฐานก่อนส่งต่อ แต่ต้องเลือกว่าจะทดสอบในสภาพใด การทดสอบผ่านใน builder ยังไม่แทนการเปิด runtime image ที่ตัดเครื่องมือออกแล้วครบทุกเส้นทาง

ลดสิ่งที่ส่งเข้าบิ้วก่อนคัดลอกเข้า image

build context อาจรวมไฟล์ในเครื่องที่ไม่ได้ตั้งใจใช้ เช่น cache, ผลบิ้วเก่า หรือไฟล์ตั้งค่าท้องถิ่น .dockerignore ช่วยกำหนดสิ่งที่ไม่ส่งเข้าบริบทตามรูปแบบที่เลือก แต่ต้องตรวจว่ารายการไม่กีดกันไฟล์ที่ขั้นบิ้วต้องใช้ด้วย

การคัดลอกทั้งโฟลเดอร์ด้วยคำสั่งกว้างทำให้เผลอพาของที่ไม่จำเป็นเข้า layer ได้ง่าย ควรจัดลำดับการคัดลอก dependency manifests กับ source ให้เหมาะกับวิธี cache และเลือกขอบเขตไฟล์ที่ต้องใช้จริง

ไฟล์ลับที่ถูกเพิ่มไปใน layer ก่อนหน้าไม่ได้ถูกทำให้ไม่เคยมีเพียงเพราะลบทิ้งใน layer ถัดไป จึงไม่ควรใช้ขั้นเพิ่มแล้วลบเป็นวิธีดูแลข้อมูลลับ ควรใช้กลไกส่งข้อมูลระหว่างบิ้วที่เหมาะสมตามเครื่องมือ และตรวจว่าสิ่งนั้นไม่ติดมากับผลปลายทาง

การใช้ cache ก็ต้องแยกว่ากำลังดูพื้นที่ cache ในเครื่องบิ้วหรือขนาด image ที่แจก เพราะการที่ดิสก์เครื่องบิ้วใช้มากไม่ได้หมายความว่าคนดึง image ต้องได้ทุกอย่างนั้นมาด้วย และการล้าง cache ไม่ได้ลด runtime image โดยตรงทุกกรณี

เล็กลงแล้วต้องเปิดใช้งานให้ครบ

ลองสร้าง container จาก runtime image ในสภาพที่ใกล้ปลายทาง โดยไม่ mount source ในเครื่องเข้ามาช่วย เพราะการทดสอบพร้อมโฟลเดอร์พัฒนาอาจเผลอทำให้ไฟล์ที่ขาดใน image ถูกเติมจากภายนอกจนดูเหมือนแพ็กครบ

ตรวจทั้งเส้นทางเริ่มแอป การติดต่อบริการที่ต้องใช้ การอ่านไฟล์ประกอบ และการเขียนลงที่เก็บที่ตั้งใจ หากเปลี่ยนไปใช้ user ที่สิทธิ์จำกัดด้วย ก็ต้องตรวจสิทธิ์ path ตามหน้าที่ ไม่แก้ด้วยการกลับไปรันทุกอย่างเป็นผู้ดูแลเพียงเพื่อให้ผ่านเร็ว

สิ่งที่ไม่ควรเกิดคือ runtime ต้องดาวน์โหลดเครื่องมือหรือ dependency เพิ่มเองทุกครั้งเพื่อชดเชยของที่ตัดออกโดยไม่ตั้งใจ เพราะจะทำให้สภาพที่นำไปรันขึ้นกับเครือข่ายและสิ่งที่ติดตั้งในเวลานั้นมากกว่าตัว artifact ที่ผ่านการตรวจ

หากแอปต้องมีข้อมูล runtime แยกต่างหากจริง ก็ควรกำหนดไว้ชัดและตรวจการเริ่มเมื่อสิ่งนั้นไม่พร้อม ไม่ปล่อยให้การลด image เปลี่ยนเงื่อนไขการ deploy โดยไม่มีใครบันทึกไว้

วัดขนาดให้เป็นชนิดเดียวกัน

เวลาจะเปรียบเทียบก่อนและหลัง ควรเก็บรุ่น source, platform ที่บิ้ว, base image และเงื่อนไขเดียวกัน แล้วระบุว่ากำลังเทียบขนาด image ที่คลายแล้ว ขนาดที่ส่งจาก registry หรือพื้นที่รวมในเครื่อง เพราะเป็นตัวเลขคนละขอบเขต

layer ที่ใช้ร่วมกันยังมีผลกับพื้นที่และเวลาที่ต้องดึงจริง หากเครื่องปลายทางมีบาง layer อยู่แล้ว ผลดาวน์โหลดก็อาจต่างจากเครื่องว่าง การจะเล่าผลจึงควรบอกสภาพ cache และวิธีวัด ไม่ใส่เปอร์เซ็นต์ลดจากสิ่งที่ยังไม่ได้ทดสอบ

บทนี้ใช้แผนภาพขั้นบิ้วกับรายการตรวจ ยังไม่มีตัวเลข MB หรือผลเวลา build ของโปรเจกต์ใด หากจะทำผลเทียบจริง ควรเก็บรายงานจาก artifact ทั้งสองชุดพร้อมผลตรวจ runtime เพื่อให้ขนาดที่ลดลงมีหลักฐานว่ามาพร้อมพฤติกรรมที่ยังครบ

สรุป

การลด image ควรเริ่มจากสิ่งที่ runtime ต้องใช้ แล้วแยกเครื่องมือเตรียมงานด้วย multi-stage และจำกัด context ให้ตรง เมื่อทดสอบ image ปลายทางโดยไม่พึ่งไฟล์จากเครื่องพัฒนา และเปรียบเทียบขนาดในขอบเขตเดียวกัน เราจะรู้ว่าตัดอะไรออกได้จริงโดยยังรักษาหน้าที่ของแอปไว้ครับ

Command Eng Logo
CMD yourNgineers
เลขประจำตัวผู้เสียภาษี0805564000814
บทความ
ติดต่อบริษัท คอมมานด์ เอ็นจ์ จำกัด
81/36 เพอร์เฟค พาร์คบางนาตำบลบางเสาธง อำเภอบางเสาธงจังหวัดสมุทรปราการ 10570
team@commandeng.in.th+66 89 393 5191
Facebook Page | Command EngLine | Command Eng Official
© Copyright 2022-2026 Command Eng Co., Ltd.v1.0.4 · 0d556ab · 2026-11-03 15:23