จากบทความเรื่อง  Intro Guide to Dockerfile Best Practices
แนะนำการเขียน Dockerfile ที่ถูกต้อง
แน่นอนว่า มันช่วยทำให้เราเข้าใจกลไกการทำงานของมันมากยิ่งขึ้น
โดยที่ Dockerfile มันคือไฟล์ที่ใช้สร้าง Docker image อีกที
หรืออาจจะเรียกว่า คู่มือหรือสูตรของการทำงานอาหาร
แต่อาหารในที่นี่คือ Docker image

ก่อนหน้านี้เรื่องของการเขียน Dockerfile นั้น
ทาง Docker ก็มีในเอกสารมาให้เลยคือ Best practices for writing Dockerfiles
ถ้าจำไม่ผิด มีคนแปลเป็นภาษาไทยเพียบ
ถ้าใครเคยอ่านและเข้าใจ 
จากนั้นก็นำไปใช้ จะชิวมาก ๆ 
เพราะว่าบทความนี้ก็ใช้ความรู้เหล่านี้นั่นเอง

ในบทความนี้แบ่งออกเป็นกลุ่มหลัก ๆ ดังนี้

กลุ่มที่ 1 Incremental build time

ในการพัฒนานั้น เรามักจะมีการเปลี่ยนแปลง Dopckerfile บ่อย ๆ
นั่นหมายความว่า
ถ้าเราไม่เข้าใจกลไกการทำงานแล้ว
อาจจะทำให้ขั้นตอนการ build Docker image จาก Dockerfile ช้ามาก ๆ

ยกตัวอย่างเช่น ทำการลบ Dockerfile ทิ้งแล้วสร้างใหม่
ผลที่ได้คือ ช้ามากมาย

ดังนั้นมาปรับปรุงกัน

เรื่องที่ 1 คือ เรื่องของ caching 

แต่ละบรรทัดของ Dockerfile นั้นคือ 1 layer
ซึ่งแต่ละ layer จะมีการทำ caching ของการ build ไว้ตามลำดับของแต่ละบรรทัด
ดังนั้นถ้าบรรทัดใดทำการแก้ไขแล้ว
Caching การ build ตั้งแต่บรรทัดนั้นไปจนถึงบรรทัดสุดท้ายจะถูกลบไปหมด
นั่นคือ ทำการ build ใหม่นั่นเอง

ดังนั้นลำดับการเขียน Dockerfile แต่ละบรรทัดจึงสำคัญ นั่นคือ ถ้าขั้นตอนอะไรเปลี่ยนแปลงบ่อย ๆ ควรอยู่บรรทัดล่าง ๆ

เรื่องที่ 2 การใช้งานคำสั่ง COPY

ต้องทำการ copy เฉพาะสิ่งที่ต้องการใช้เท่านั้น
ไม่ใช่ copy ของที่ไม่จำเป็นเข้าไป
เพราะว่า มันจะส่งผลให้ caching ถูกลบไป
นั่นก็ส่งผลต่อเวลาการ build เช่นกัน
สามารถกรองสิ่งที่ไม่ต้องการด้วยการใช้งาน .dockerignore ได้อีกด้วย

เรื่องที่ 3 การ update หรือ install library ควรอยู่ด้วยกัน

ไม่ควรแยกบรรทัดกัน
เพราะว่า อาจจะทำให้เกิดปัญหาการใช้ library ผิด version หรือไม่ update นั่นเอง
รวมทั้งให้เรื่องนี้อยู่ใน caching ตัวเดียวกัน    

กลุ่มที่ 2 Reduce image size

ลดขนาดของ Docker image เป็นสิ่งที่สำคัญมาก ๆ
ทั้งช่วยลดขนาดของ Disk ที่ใช้จัดเก็บ
ทั้งช่วยเรื่องเวลาในการ deploy ที่รวดเร็วขึ้น
ดังนั้นมาปรับปรุงกัน

เรื่องที่ 1 อะไรที่ไม่จำเป็นก็ไม่ต้องเอาเข้ามา

ยกตัวอย่างเช่นพวก library ต่าง ๆ นั่นเอง
แต่ถ้าต้องการใช้งาน อาจจะติดตั้งภายหลังและลบทิ้งไป

เรื่องที่ 2 ลบพวกไฟล์ และ folder cache ต่าง ๆ จากการติดตั้ง library ต่าง ๆ

รวมทั้งยังสามารถนำ Multi-stage build มาช่วยได้อีก

กลุ่มที่ 3 Maintainability

การดูแลรักษาที่ง่ายขึ้น
เป็นอีกเรื่องที่ไม่ยากต่อการทำและเข้าใจ
แต่มักจะผิดบ่อย ๆ ดังนี้

เรื่องที่ 1 แนะนำให้ใช้ Official Docker image

นั่นหมายความว่า
ก่อนที่จะใช้งาน Docker image อะไรให้ดูว่ามาจาก official website หรือต้นน้ำหรือไม่
เพื่อทำให้เรามั่นใจว่า จะได้รับการดูแลรักษาอย่างดี
สามารถเข้าไปดูได้ใน Docker Hub จะบอกหมดว่าเป็น Image ประเภทไหน

เรื่องที่ 2 กรุณาระบุ tag ของ Docker image ที่จะใช้งาน

แต่ห้ามระบุ tag ชื่อว่า latest นะ
เพราะว่า tag นี้จะเปลี่ยนไปเรื่อย ๆ
มิเช่นนั้นขั้นตอนของการ build จะพังเรื่อย ๆ แบบงง ๆ

เรื่องที่ 3 พยายามเลือก Docker image ที่มีขนาดเล็ก

เรื่องนี้พูดยาก เพราะว่ามันขึ้นอยู่กับความต้องการด้วย
แต่ถ้า Docker image ที่เลือกมีความสามารถเหมือนกัน
แนะนำให้เลือกที่เล็กกว่าไว้ก่อน

กลุ่มท่ี 4 Reproducibility

Dockerfile นั้นคือคู่มือสำหรับการสร้าง Docker image
ดังนั้นเรื่อง consistency หรือความถูกต้องในทุก ๆ ครั้งที่ทำการสร้าง
หรือสามารถ reproduce Docker image ซ้ำ ๆ ได้อย่างถูกต้อง
ถ้าขาดเครื่องนี้ไป
การใช้งาน docker หรือโลกของ containerization ก็น่าจะไร้ประโยชน์สุด ๆ
ดังนั้นมาทำให้มันทำงานได้ซ้ำ ๆ กัน

เรื่องที่ 1 ทำการ build จาก source code เลย

ไม่ควรทำการ build artifact หรือ software package จากข้างนอก
จากนั้นทำการ copy เข้าไปยัง Docker image อาจจะก่อให้เกิดปัญหาได้
เช่น build ผิด version หรือผิด OS เป็นต้น
ดังนั้นสิ่งที่ควรทำคือ ทำการ copy source code เข้ามา build ใน Dockerfile เลย
ทำให้เราสามารถควบคุมสิ่งแวดล้อมรอบข้างได้เลย
แน่นอนว่า ทำซ้ำได้

เรื่องที่ 2 แยกขั้นตอนของการ download และติดตั้ง dependency/library ออกมา

ปัญหาหลัก ๆ ของการ build Docker image ของระบบงานคือ
การ download และติดตั้ง dependency/library นั่นเอง
ดังนั้นเราควรแยกขั้นตอนนี้ออกมา
เพื่อช่วยให้จัดการเรื่อง caching ได้ดียิ่งขึ้น
นั่นหมายความว่า
ถ้าเราไม่ทำการเปลี่ยนแปลงหรือเพิ่ม dependency/library แล้ว
ขั้นตอนการสร้าง Docker image ก็ควรใช้งาน caching ที่เก็บไว้
ซึ่งมีความสำคัญอย่างมาก

ดังนั้นสิ่งที่ควรคิดคือ
แยกขั้นตอนการติดตั้ง dependency/library 
ออกจากการ build/compile ของระบบงานออกจากกัน

เรื่องที่ 3 แนะนำให้ใช้งาน Multi-stage build เลย

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