Docker Images เป็น Immutable (ไม่เปลี่ยนแปลง) เมื่อ Build เสร็จ มันไม่เปลี่ยน แน่นอนความสม่ำเสมอ ความคาดเดาได้ และความเสถียร Container ทุกตัวจาก Image เดียวพฤติกรรมเหมือนกัน Versioning ปลอดภัยและง่าย แต่ถ้าต้องการปรับอะไรใน Container ที่รันอยู่? เช่น ติดตั้ง Package หรือแก้ Config? นี่คือที่ที่ docker commit เข้ามาช่วย มัน Capture การเปลี่ยนแปลงใน Container ที่รันอยู่ และสร้าง Image ใหม่โดยไม่แตะ Image ต้นฉบับ เหมาะสำหรับทดสอบ Fixes, Iterate เร็ว และ Rollout Custom Images โดยไม่ต้อง Rebuild จากศูนย์
ทำไม Docker Images ถึงไม่เปลี่ยน
Docker Images ประกอบด้วย Read-only Layers หลายชั้น ตอน Run Container Docker เพิ่ม Writable Layer บนสุด เรียกว่า Container Layer การเปลี่ยนแปลงใดๆ เกิดขึ้นเฉพาะ Layer บนสุดนี้ ลบ Container แล้ว การเปลี่ยนแปลงใน Layer นั้นหายไป Image ต้นฉบับคงเดิม
Design นี้รับประกันประโยชน์:
- Container ทุกตัวจาก Image เดียว พฤติกรรมเหมือนกัน → Consistency
- การเปลี่ยนแปลงใน Container หนึ่ง ไม่กระทบอีกตัว → Predictability
- Tag Image Versions ได้ปลอดภัยโดยไม่มีความเสี่ยง
Design ให้ Stability ดี แต่จำกัดตอนอยากแก้ไขเร็วใน Running Container นี่คือที่ docker commit ช่วย
สร้าง Image ใหม่จาก Running Container
รัน docker commit Docker Capture สถานะปัจจุบันของ Running Container สร้าง Image ใหม่ มัน Snapshot File System ของ Container บันทึกการเปลี่ยนแปลงที่ทำ: ติดตั้ง Packages, แก้ Configs, แก้ไขไฟล์ เป็น Layer ใหม่ Image ต้นฉบับไม่ถูกแตะ ทดลองและ Iterate เร็วได้
เหมาะสำหรับ: เซฟ Custom Base Setup ไว้ใช้ซ้ำ, ใช้ Fixes/Config Changes เล็กน้อยระหว่างทดสอบ, แชร์ Image ที่อัปเดตให้ Team โดยไม่ต้อง Rebuild Dockerfile จากศูนย์
Syntax docker commit สร้าง Image ใหม่จาก Running Container:
docker commit [OPTIONS] CONTAINER_ID NEW_IMAGE_NAME[:TAG]
CONTAINER_ID = ID หรือชื่อ Container ที่จะ Capture NEW_IMAGE_NAME = ชื่อ Image ใหม่ TAG = Optional Default คือ latest
หมายเหตุ: docker commit เป็น Legacy Alias ของ docker container commit ทั้งคู่เหมือนกัน
Options ของ docker commit ใส่ Metadata, ใช้ Config Changes, ควบคุมพฤติกรรม Commit ตารางสรุป Options:
| Option | Long Form | Description | Example |
|---|---|---|---|
| -a | --author | เพิ่มชื่อ Author ใน Metadata Image ใหม่ | docker commit -a "Anees" my-container my-image |
| -c | --change | ใช้ Dockerfile Instructions (ENV, LABEL, CMD) กับ Image ใหม่ | docker commit -c "ENV APP_ENV=prod" my-container my-image |
| -m | --message | เพิ่มข้อความสั้นอธิบายการเปลี่ยนแปลงใน Image | docker commit -m "Installed curl" my-container my-image |
| -p | --pause | Pause Container ระหว่าง Commit เพื่อ Consistency (Default: true) | docker commit --pause=false my-container my-image |
ดู docker commit ทำงานจริง
สมมติอยากติดตั้ง curl ใน Alpine Container โดยไม่ Rebuild Dockerfile รัน Container จาก Base Image:
docker run -it alpine:latest /bin/sh
เข้า Container แล้ว ทำการเปลี่ยนแปลง:
apk update && apk add curl
ออกจาก Container:
exit
Commit Container เป็น Image ใหม่:
docker commit alpine-with-curl:1.0
ตรวจสอบ Image ใหม่:
docker images
ตอนนี้มี Image ใหม่พร้อมรันได้ทุกที่ มี curl ติดตั้งไว้แล้ว
รัน Image ใหม่ทดสอบการเปลี่ยนแปลงที่เซฟไว้
หลังสร้าง Image ใหม่ รัน Container จากมันเพื่อ Verify ว่าการเปลี่ยนแปลงเซฟไว้จริง:
docker run -it alpine-with-curl:1.0 /bin/sh
คำสั่งเปิด Interactive Shell ใน Container จาก Image alpine-with-curl:1.0 เข้าไปเช็คว่าการแก้ไขคงอยู่:
curl --version
แสดงว่า Changes คงอยู่ใน Image ใหม่
docker commit vs Dockerfile: ใช้ตัวไหนเมื่อไหร่
ทั้ง Dockerfile และ docker commit สร้าง Docker Images ได้ แตทำงานต่างกันจริง และเหมาะสถานการณ์ต่างกัน
Dockerfile เหมาะสำหรับ Builds ที่น่าเชื่อถือและทำซ้ำได้ โดยเฉพาะ CI/CD Pipelines และ Production Environments เก็บการเปลี่ยนแปลงทั้งหมดใน Code ชัดเจน Track, Review, Version-control ได้ตลอดเวลา Approach นี้รับรองว่าใคร Build Image ภายหลังได้ผลเหมือนกัน Critical สำหรับ Maintenance และ Team Collaboration ยาวนาน
แตกต่างกัน docker commit ใช้ได้ดีสำหรับ Quick Fixes, Testing, หรือ Adjustments เล็กๆ ที่อยากลองโดยไม่ Rewrite/Rebuild Dockerfile ทั้งหมด ใช้ตอน Experiment, Debug, หรือ Validate Change On-the-fly แต่เพราะ Changes ไม่ได้ Documented ใน File วิธีนี้เหมาะ Short-term Use แทน Production
สรุป: ใช้ docker commit สำหรับ Experiment หรือ Temporary Fixes สำหรับ Production-ready Images ควรใช้ Dockerfile เสมอ เพื่อใช้ Docker ให้เกิดประโยชน์สูงสุด คุ้มค่าที่จะสำรวจคำสั่งสำคัญอื่นๆ ที่ทำให้จัดการ Containers, Images, Workflows ง่ายขึ้น