Docker Image คืออะไร?
Docker image คือ packages ของ software ที่เตรียมไว้ให้คุณนำไปใช้ run application(ต้องนำไปสร้างเป็น container ก่อนถึงจะ run application ได้)
เราจะนำ Docker Image มาจากไหน
เราจะนำ docker image มาใช้งานเราจะมีทางเลือกอยู่ 2 ทางคือ
-
นำ Image ที่คนอื่นเค้าเตรียมไว้ให้ ซึ่งเราจะต้อง pull image ลงมาจาก container registry ซึ่ง Container registry จะมีอยู่ 2 ประเภทคือ
- Public เป็น container registry ที่เปิดให้เราเอา image ของเค้าลงมาใช้ได้เลย container registry ที่เราจะรู้จักกันมาที่สุดคือ docker hub แต่นอกจากนี้เรายังสามารถ เลือก image จาก vender เจ้าอื่นๆได้อีกมากมาย
- Private เป็น container registry ที่อยู่ภายในองค์กร ซึ่งอาจเเป็น Server ที่อยู่ในองค์กร หรืออยู่บน Cloud ก็ได้
คำสั่งที่เราใช้ในการ Download image ลงมาจาก container registry คือ
$ docker pull [ชื่อ image]
-
เราสามารถ Build image ของเราเองได้การเขียน Dockerfile และ run คำสั่ง
$ docker build -t [ชื่อ image] .
อ่านวิธีการเขียน Dockerfile แบบละเอียดๆ ได้ที่บทความนี้
จาก Image สู่ Container
เราจะไม่สามารถทำงานกับ Docker Image ได้ เราต้องนำ Docker Image นั้นไปสร้างเป็น Container ก่อนจึงจะสามารถใช้งานได้ ซึ่งจะเป็นดังรูป
เราสามารถสร้าง container กี่ตัวก็ได้จาก Image ตัวเดียวกันเนื่องจากการทำงานของ container จะเป็น layer ดังนั้น layer ด้านล่างจะเป็น read-only จะเป็น software ที่มีการทำงานเหมือนเดิมตลอดเวลา ดังนั้น Container ทุกตัวสามารถ re-use ใช้ Image ตัวเดียวกันได้ ส่วน layer ของ container จะเป็นส่วนที่มีการเปลี่ยนแปลงเราสามารถ read-write ได้
Docker Image จะถูกกำหนดรูปแบบของ Image ด้วน OCI(Open Container Initiative) ดังนั้นเราสามารถนำ Docker Image ไปสร้าง Container ด้วย container run-time ตัวอื่นๆได้
Docker commands สำหรับจัดการกับ Docker Image
docker จะมีคำสั่งสำหรับการทำงานกับ docker image อยู่เยอะมากๆ โดยจะแยกออกเป็นกลุ่มต่างๆ ดังนี้
คำสั่งสำหรับการ Build Docker Image
เราสามารถ build docker image ขึ้นมาเองด้วยคำสั่ง โดยจะระบุการสิ่งที่มีใน docker image นี้ด้วย Dockerfile หลังจากเขียน Dockerfile แล้วเราก็จะเข้า run คำสั่งนี้ใน path ที่มี Dockerfile
$ docker build -t <image_name> .
ถ้าเกิดปัญหาระหว่างการ build ให้ลองกลับไปเริ่มต้น build ใหม่ตั้งแต่ต้น ด้วย parameter –no-cache ซึ่งจะเหมือนกับการ clear cache ในกระบวนการ build
$ docker build -t <image_name> . –no-cache
ในกรณีที่เรามี Dockerfile มากกว่า 1 ไฟล์ เช่น Docker ของ Bach-End ที่เป็น NodeJS เราอาจตั้งชื่อว่า node.dockerfile เราจะบอกให้ใช้ node.dockerfile ในการ build ด้วย parameter -f
$ docker build -t <image_name> . –f node.dockerfile
คำสั่งที่ใช้ในการดึง Docker Image
เราสามารถดึงเอา image ทั้งหมดที่อยู่บนเครื่องนี้ออกมาดูด้วยคำสั่ง
$ docker images
# หรือ
$ docker image ls # ถ้าใช้ ls คำว่า image จะไม่เติม s
ถ้าต้องการค้นหาตามชื่อ image ต่อท้ายด้วยชื่อ image แบบนี้
$ docker images ubuntu
และถ้าต้องการค้นหาตาม tag ให้ต่อท้ายด้วย : แล้วตามด้วย tag ที่ต้องการค้นหา เช่น
$ docker images ubuntu:rolling
ค้นหา Dangling Image
ในกรณีที่เราต้องค้นหา image ที่เป็น dangling image ซึ่งหมายถึง image ที่ไม่ได้ใช้แล้ว เกิดจากการที่ เราทำการ build image ขึ้นมาใหม่แต่ไม่ได้เปลี่ยนชื่อหรือตั้งชื่อใหม่ docker จะ build image นั้นขึ้นมาในชื่อเดิม ทำให้ image ใน version ก่อนหน้าถูกเปลี่ยนเป็น dangling image(ชื่อของ image จะกลายเป็น
$ docker images --filter "dangling=true"
image ที่ Build ขั้นมาแล้วแต่ไม่ได้นำไปสร้าง container เราจะเรียกว่า Unused image ซึ่งไม่ใช่ Dangling image
ค้นหาตามช่วงเวลา
เราสามารถค้นหา image ตามเวลาที่เกิดก่อนหรือหลังได้
ตัวอย่าง ตอนนี้เรามี image อยู่ 3 ตัวคือ
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
image1 latest eeae25ada2aa 4 minutes ago 188.3 MB
image2 latest dea752e4e117 9 minutes ago 188.3 MB
image3 latest 511136ea3c5a 25 minutes ago 188.3 MB
เรียงลำดับตามการ buid image ดังนี้
- image3 เกิดมานานสุด 25 นาที
- image2 เกิดก่อน image1 แต่เกิดหลัง image3
- image1 เกิดหลังสุด เพิ่งจะมีอายุ 4 นาที
ถ้าเราต้องการ image ที่เกิดก่อน image1 เราจะ filter ด้วย before=image1
$ docker images --filter "before=image1"
ผลลัพธ์จะออกมาแบบนี้
REPOSITORY TAG IMAGE ID CREATED SIZE
image2 latest dea752e4e117 9 minutes ago 188.3 MB
image3 latest 511136ea3c5a 25 minutes ago 188.3 MB
แต่ถ้าเราต้องการ image ที่เกิดหลังจาก image3 เราจะ filter ด้วย since=image3
$ docker images --filter "since=image3"
ผลลัพธ์จะออกมาแบบนี้
REPOSITORY TAG IMAGE ID CREATED SIZE
image1 latest eeae25ada2aa 4 minutes ago 188.3 MB
image2 latest dea752e4e117 9 minutes ago 188.3 MB
จัดรูปแบบของผลลัพธ์ที่ออกมาจากคำสั่ง docker images
เราสามารถเลือก column ในการแสดงผล ด้วย parameter –format
docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}'
ในตัวอย่างนี้จะเปลี่ยนการแสดงผล 2 columns คือ
- เปลี่ยนจาก column Created ที่ระบุว่า Docker image นี้สร้างมานานเท่าไหร่แล้ว ไปเป็น CreatedAt ที่ระบุวันและเวลาที่สร้าง image นี้ขึ้นมา
- เพิ่ม column Size ขึ้นมาใหม่ เพื่อที่เราจะได้เห็นขนาดของ image ที่เรานำมาใช้ว่าใหญ่เกินไปหรือไม่
เราควรจะใช้ Image ที่มีขนาดเล็ก เพราะขนาดของ Image ยิ่งใหญ่ยิ่งมี application เยอะ ยิ่งมีความเสี่ยง
คำสั่งที่ใช้ในการลบ Docker Image
เราสามารถลบ image ที่ต้องการได้ด้วยคำสั่ง
$ docker rmi [ชื่อ image]
ใช้ร่วมกับคำสั่ง docker images ในหัวข้อก่อนหน้าได้ (คำสั่งใช้ได้เฉพาะบน MacOS และ Linux)
# ลบทุกๆ image ที่มีอยู่ในเครื่อง
$ docker rmi $(docker images -q)
หรือถ้าต้องการลบเฉพาะ Dangling image ก็สามารถใส่ parameter -f เพิ่มเข้าไปแบบนี้
# ลบเฉพาะ Dangling image เท่านั้น
$ docker rmi $(docker images -f "dangling=true" -q)
parameter -q เป็นการใช้ quiet mode คือ command ที่ใส่ -q เข้าไปจะ return แค่ id กลับมาเท่านั้น เช่น
$ docker images -q
ผลลัพธ์จะออกมาเป็นแบบนี้ ผลลัพธ์จะออกมาแต่ Image ID เท่านั้น
5628e5ea3c17
5d3887e514fe
289dc403af49
เราจะใส่ -q เข้าไปในทุกๆ sub expression
คำสั่งที่ใช้ในการลบ Docker Image ที่ไม่ได้ใช้(Prune)
การ prune คือการลบสิ่งที่ไม่ต้องการออก ตามความหมายของคำว่า prune ซึ่งแปลว่า ตัด,แต่ง ซึ่ง docker image prune จะมี parameters ต่างๆ ดังนี้
ลบ Unused Image
ถ้าเราต้องการลบ Image ที่ไม่ได้ใช้งานซึ่งประกอบไปด้วย
- Unused Image Image ที่ไม่ได้นำไปสร้างเป็น container
- Dangling Image ถ้าเรา run คำสั่ง dokcer build โดยไม่ได้เปลี่ยนชื่อ image หรือ tag docker จะเปลี่ยนชื่อ image ตัวเก่าเป็น
ซึ่งเราจะเรียก image ตัวเก่านี้ว่า dangling image
ดังนั้นถ้าต้องการลบ image ที่ไม่ได้ใช้ออกทั้งหมดให้ใช้คำสั่ง
$ docker image prune -a
เราต้องคอย prune -a บ่อยๆ จะได้นำพื้นที่ใน disk กลับมาใช้งานให้คุ้มค่า
Force
ถ้าต้องการลบเลยโดยไม่ต้อง confirm ให้ใส่ -f หรือ –force
$ docker image prune -f
การ Prune แบบมีเงื่อนไข
เวลาเรา prune เราไม่จำเป็นต้องลบออกทั้งหมดเราสามารถเลือก image ที่ต้องการ prune โดยใช้ –filter ต่อท้ายเข้าไปแบบนี้ เช่น
ต้องการให้ prune image ที่สร้างขึ้นมา ก่อนวันที่ 4 ธันวาคม 2023
$ docker image prune --filter "until=2023-12-04T00:00:00"
ต้องการให้ prune image ที่สร้างขึ้นมามากกว่า 10 วันแล้ว(240 ชั่วโมง)
$ docker image prune -a --force --filter "until=240h"
ต้องการให้ prune image ที่มี label ชื่อ deprecated โดยที่ไม่ได้สนใจว่า deprecated จะมีค่าเป็นอะไร
$ docker image prune --filter="label=deprecated"
ต้องการให้ prune image ที่มี label ชื่อ maintainer โดยที่ maintainer ต้องมีค่าเป็น john
$ docker image prune --filter="label=maintainer=john"
ต้องการให้ prune image ที่ไม่มี label ชื่อว่า maintainer
$ docker image prune --filter="label!=maintainer"
ต้องการให้ prune image ที่มี label ไม่ได้มี maintainer เป็น john
$ docker image prune --filter="label!=maintainer=john"
นอกจากเราจะลบ image ออกแล้วเราควรลบสิ่งที่ไม่ได้ใช้ออกทั้งหมด ดังนั้นเราสามารถลบสิ่งที่ไท่ได้ใช้ออกทั้งหมดด้วยคำสั่ง
$ docker system prune -a
# หรือ
$ docker system prune --all
โดยที่ืคำสั่ง docker system prune จะลบสิ่งต่างๆ ดังต่อไปนี้
- container ที่ stop อยู่ทั้งหมด
- network ที่ไม่มี container อยู่ในนั้นเลย
- dangling images ทั้งหมด
- build cache ทั้งหทด
ซึ่งจะเห็นว่า prune -a จะไม่ได้รวม volume เข้ามาด้วย(volume ที่ไม่ได้ใช้จะไม่ถูกลบออก) ดังนั้นถ้าเราต้องการลบ volume ออกด้วยให้เพิ่ม -v หรือ –volumes ต่อท้ายเข้าไปแบบนี้
$ docker system prune -a -v
# หรือ
$ docker system prune --all --volumes