Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ระบบ >> Linux

Docker Commit: สร้าง Image ใหม่จาก Container ที่รันอยู่ ทันที ไม่ต้อง Rebuild Dockerfile

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 เร็วได้

Docker Commit: สร้าง Image ใหม่จาก Container ที่รันอยู่ ทันที ไม่ต้อง Rebuild Dockerfile

เหมาะสำหรับ: เซฟ 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:

OptionLong FormDescriptionExample
-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เพิ่มข้อความสั้นอธิบายการเปลี่ยนแปลงใน Imagedocker commit -m "Installed curl" my-container my-image
-p--pausePause 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
Docker Commit: สร้าง Image ใหม่จาก Container ที่รันอยู่ ทันที ไม่ต้อง Rebuild Dockerfile

ออกจาก Container:

exit

Commit Container เป็น Image ใหม่:

docker commit alpine-with-curl:1.0
Docker Commit: สร้าง Image ใหม่จาก Container ที่รันอยู่ ทันที ไม่ต้อง Rebuild Dockerfile

ตรวจสอบ Image ใหม่:

docker images

ตอนนี้มี Image ใหม่พร้อมรันได้ทุกที่ มี curl ติดตั้งไว้แล้ว

Docker Commit: สร้าง Image ใหม่จาก Container ที่รันอยู่ ทันที ไม่ต้อง Rebuild Dockerfile

รัน 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: สร้าง Image ใหม่จาก Container ที่รันอยู่ ทันที ไม่ต้อง Rebuild Dockerfile

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 ง่ายขึ้น