กลับไปหน้าบทความ
#Docker#DevOps#CI/CD#การพัฒนา#คอนเทนเนอร์

10 เคล็ดลับ Docker ที่ช่วยให้พัฒนาเร็วขึ้นอย่างเห็นผล

การใช้งาน Docker ให้มีประสิทธิภาพไม่ได้ขึ้นอยู่กับเทคนิคเพียงข้อเดียว แต่เกิดจากการจัดการ build, cache, storage, network และการ debug อย่างเป็นระบบ บทความนี้สรุป 10 tips สำคัญที่ช่วยให้ทีมพัฒนาเร็วขึ้น ใช้ทรัพยากรคุ้มขึ้

20 มกราคม 2569อ่านประมาณ 2 นาที

แชร์บทความ

10 เคล็ดลับ Docker ที่ช่วยให้พัฒนาเร็วขึ้นอย่างเห็นผล

10 เคล็ดลับ Docker ที่ช่วยให้พัฒนาเร็วขึ้นอย่างเห็นผล

Docker เป็นเครื่องมือสำคัญของงานพัฒนาซอฟต์แวร์ยุคใหม่ แต่การใช้งานแบบพื้นฐานอาจยังไม่ดึงประสิทธิภาพออกมาได้เต็มที่ หากรู้จักปรับวิธี build, จัดการ image, แคช, log และการ debug ให้เหมาะสม ก็จะช่วยให้ทั้งเครื่องนักพัฒนาและระบบ CI/CD ทำงานได้เร็วและลื่นขึ้นอย่างชัดเจน

1) ใช้ .dockerignore อย่างจริงจัง

หนึ่งในจุดที่หลายทีมมองข้ามคือการลดขนาด build context ก่อนส่งเข้า Docker daemon เพราะยิ่งมีไฟล์ที่ไม่จำเป็นมาก การ build ก็ยิ่งช้าโดยไม่จำเป็น

ไฟล์ที่มักควรใส่ไว้ใน .dockerignore เช่น

  • node_modules
  • .git
  • dist
  • coverage
  • *.log

ข้อดีของการทำเช่นนี้คือส่งไฟล์เข้า Docker น้อยลง ลดภาระการ build ทำให้ layer cache ทำงานได้ดีขึ้น และช่วยให้ pipeline ใน CI เร็วขึ้นด้วย

2) ใช้ Multi-stage build เพื่อลดขนาด image

Multi-stage build เป็นเทคนิคที่ช่วยแยกขั้นตอนการ build ออกจากขั้นตอน runtime อย่างชัดเจน โดยในช่วง build สามารถใช้ compiler หรือ SDK ขนาดใหญ่ได้เต็มที่ แต่ใน final image ควรคงไว้เฉพาะสิ่งที่จำเป็นต่อการรันจริง

แนวทางนี้ช่วยให้

  • image มีขนาดเล็กลงมาก
  • deploy ได้เร็วขึ้น
  • ลดพื้นที่จัดเก็บ
  • ลดช่องโหว่จากแพ็กเกจที่ไม่จำเป็น

สำหรับ final stage ควรเลือก base image ที่เล็กและเหมาะกับการใช้งาน เช่น alpine หรือ distroless เพื่อให้ runtime environment กระชับที่สุด

3) เข้าใจ Layer cache และเขียน Dockerfile ให้แคชติด

Docker ทำงานแบบเป็นเลเยอร์ หากคำสั่งในชั้นก่อนหน้าไม่เปลี่ยน ระบบจะใช้ cache เดิมได้ทันที ดังนั้นลำดับคำสั่งใน Dockerfile จึงมีผลโดยตรงต่อความเร็วในการ build

หลักสำคัญคือให้เรียงคำสั่งจากสิ่งที่เปลี่ยนน้อยไปหาสิ่งที่เปลี่ยนบ่อย ตัวอย่างเช่น

  • ติดตั้ง dependency ก่อน
  • ค่อย copy source code ตามหลัง

อีกเทคนิคที่ใช้ได้ผลมากคือ copy ไฟล์ lock เช่น package-lock.json, yarn.lock หรือ poetry.lock แยกก่อน เพื่อให้ขั้นติดตั้ง dependency ไม่ต้องรันใหม่ทุกครั้งเมื่อมีการแก้โค้ดเล็กน้อย

4) เลือกใช้ Bind mount และ Volume ให้เหมาะกับงาน

แม้ทั้งสองแบบจะใช้เชื่อมข้อมูลระหว่าง host กับ container ได้ แต่เหมาะกับคนละกรณี

Bind mount

เหมาะกับงานพัฒนา เพราะเมื่อแก้โค้ดบนเครื่อง ไฟล์จะสะท้อนเข้า container ทันที ทำให้รอบการพัฒนาเร็วขึ้น

Volume

เหมาะกับข้อมูลที่ต้องการความต่อเนื่องและจัดการโดย Docker เช่น

  • ฐานข้อมูล
  • cache
  • uploads

Volume มักเหมาะกว่าในกรณีข้อมูลถาวร และบางสถานการณ์อาจมีประสิทธิภาพด้าน I/O ดีกว่า bind mount ด้วย

5) ตั้ง HEALTHCHECK ให้ container บอกสถานะตัวเองได้

หลายครั้ง service ภายในล่มไปแล้ว แต่ container ยังอยู่ในสถานะ running ทำให้ระบบภายนอกเข้าใจผิดว่ายังพร้อมใช้งาน การกำหนด HEALTHCHECK ช่วยให้ orchestrator หรือ Docker Compose ตรวจจับได้ว่าบริการยังตอบสนองได้จริงหรือไม่

แนวทางที่ดีคืออย่าตรวจแค่ว่า port เปิดอยู่ แต่ควรเช็ก endpoint สำคัญ เช่น

  • /health
  • /ready

วิธีนี้ช่วยให้การ restart อัตโนมัติหรือการจัดการ service ทำได้แม่นยำขึ้น

6) จัดการ Log ไม่ให้กินดิสก์โดยไม่รู้ตัว

ค่าเริ่มต้นของ log ใน Docker อาจสะสมไปเรื่อย ๆ จนใช้พื้นที่มากโดยไม่ทันสังเกต โดยเฉพาะในเครื่องพัฒนาและ server ที่รันต่อเนื่องเป็นเวลานาน

สิ่งที่ควรทำคือ

  • ตั้ง log rotation
  • จำกัดขนาดไฟล์ log
  • จำกัดจำนวนไฟล์ที่เก็บ

อีกแนวทางที่ดีคือส่ง log ไปยัง stdout และ stderr แล้วให้ระบบ log collector จัดการต่อ วิธีนี้ช่วยให้เครื่องไม่เต็มเงียบ ๆ และทำให้การติดตามปัญหาง่ายขึ้นด้วย

7) ใช้ docker system prune อย่างปลอดภัย

คำสั่ง prune ช่วยล้าง image, container, network หรือ cache ที่ไม่ได้ใช้งาน เพื่อคืนพื้นที่ดิสก์ แต่ถ้าใช้อย่างไม่ระวังอาจลบข้อมูลสำคัญได้

แนวทางที่ปลอดภัยคือ

  • ตรวจสอบรายการก่อนลบ
  • ใช้ตัวกรองตามอายุ เช่นลบเฉพาะสิ่งที่ไม่ใช้เกิน 7 วัน
  • ระวังการลบ volume โดยเฉพาะถ้ามีข้อมูลฐานข้อมูลอยู่ภายใน

การ prune ที่รอบคอบช่วยให้ได้พื้นที่คืนโดยไม่สร้างความเสียหายตามมา

8) ตั้งชื่อ network ให้สื่อความหมาย

การตั้งชื่อ network อย่างเป็นระบบช่วยเรื่องการ debug มากกว่าที่คิด เพราะทำให้รู้ทันทีว่า network นั้นอยู่ในโปรเจกต์ใด หรือใช้กับสภาพแวดล้อมใด

นอกจากนี้การใช้ custom bridge network ยังช่วยให้ service ต่าง ๆ ติดต่อกันผ่านชื่อ service ได้สะดวก ลดความจำเป็นในการ hardcode IP address และทำให้การจัดการ service discovery ง่ายขึ้นมาก

9) ใช้ Compose profiles เพื่อแยกชุดบริการตามงาน

ในหลายโปรเจกต์ ไม่จำเป็นต้องเปิดทุก service พร้อมกันตลอดเวลา เช่น ระหว่างพัฒนาอาจต้องการเพียง API และฐานข้อมูล แต่ยังไม่ต้องใช้ tracing, Kafka หรือ worker ทั้งระบบ

Compose profiles จึงเป็นตัวช่วยที่ดีในการเลือกเปิดเฉพาะชุดบริการที่ต้องใช้ เช่น

  • dev
  • full
  • observability

ผลลัพธ์คือ

  • เปิดเครื่องได้เร็วขึ้น
  • ใช้ทรัพยากรน้อยลง
  • ลดความซับซ้อนระหว่างการพัฒนา
  • ทำให้ทีมทำงานได้คล่องขึ้น

10) Debug ด้วย exec และ inspect ให้เป็น

เมื่อเกิดปัญหาใน container เครื่องมือพื้นฐานที่ทรงพลังมากคือ docker exec และ docker inspect

docker exec

ใช้เข้าไปตรวจสอบภายใน container เช่น

  • ดูไฟล์ environment
  • เช็ก process
  • ทดสอบ curl ภายใน network

docker inspect

ใช้ดูค่าจริงที่ container กำลังใช้งานอยู่ เช่น

  • mounts
  • networks
  • health status
  • command ที่ใช้รัน

เทคนิคที่มีประโยชน์มากคือเมื่อเจอสถานการณ์แบบ “รันได้ในเครื่องฉัน” ให้ใช้ inspect เปรียบเทียบระหว่างสองเครื่อง จะช่วยมองเห็นความต่างได้เร็วและตรงจุด

โบนัส: ตั้ง image tag ให้ตามรอยได้ง่าย

อีกเรื่องที่หลายทีมยังทำไม่สม่ำเสมอคือการตั้ง tag ของ image ให้มีทั้งหมายเลขเวอร์ชันและ git commit ประกอบกัน

ข้อดีคือ

  • ย้อนกลับเวอร์ชันได้ง่าย
  • ไล่บั๊กได้เร็วขึ้น
  • ลดการเดาว่า image ไหนมาจากโค้ดชุดใด
  • ช่วยให้การ deploy และ rollback มีความน่าเชื่อถือมากขึ้น

สรุป

การทำให้ Docker เร็วขึ้นและใช้งานได้ดีขึ้นไม่ได้มาจากเทคนิคข้อใดข้อหนึ่งเพียงลำพัง แต่เกิดจากการปรับหลายส่วนร่วมกัน ทั้งการลดขนาด build context, ใช้ multi-stage build, เขียน Dockerfile ให้แคชติด, เลือก storage ให้เหมาะ, จัดการ log และ debug อย่างมีระบบ

เมื่อ Docker ถูกจัดระเบียบอย่างดี นักพัฒนาจะทำงานได้ลื่นขึ้น ระบบ CI/CD จะมีประสิทธิภาพขึ้น และทั้งทีมจะสัมผัสได้ถึง dev experience ที่ดีขึ้นในทุกวัน