สร้าง Image กันต่อ
จากตอนที่แล้วเรารู้วิธีการสร้าง Image กันแล้วซึ่งเป็นการใช้ Dockerfile แล้วก็ใช้คำสั่งต่างๆใน Dockerfile ไม่ว่าจะเป็น FROM RUN ADD แต่เรายังขาดคำสั่งสำคัญอยู่ซึ่งมันสำคัญมาก (แล้วทำไมไม่พูดตอนที่แล้ว ฮ่าๆๆๆๆ) ซึ่งมันคือคำสั่ง CMD และ ENTRYPOINT ซึ่งเป็นคำสั่งซึ่งกำหนดว่า container ที่สร้างจาก Image พอสร้างเสร็จแล้วจะให้เขาทำงานด้วยคำสั่งอะไร
CMD
มาเริ่มที่คำสั่ง CMD กันก่อน อันนี้เราลองไปดู Image คนอื่นกันก่อน
Image httpd เขา Show dockerfile ของเขาให้ดูประมาณนี้ https://hub.docker.com/layers/httpd/library/httpd/latest/images/sha256-1fa8b506b23df25b3e2570cd27eb7a88c6d1622e749b7931e9a7f8390d17777b
จากภาพจะเห็นว่า CMD ที่กรอบแดงไว้เรียกใช้คำสั่ง httpd-foreground ซึ่งเมื่อเราลองสั่ง
1 | docker run --name test_httpd httpd |
จะได้ดังภาพ
ซึ่งตรงกับที่บอกไว้ในคำสั่ง CMD ตรงนี้อาจจะบอกว่ามั่วรึเปล่า งั้นเรามาเปลี่ยน CMD กันดูว่าถ้าเราทำการแก้ไข CMD กันดูแล้วดูว่าจะมีการเปลี่ยนเปลงหรือไม่ โดยทำการสร้างไฟล์ Dockerfile ขึ้นมาโดยใส่คำสั่งในการสร้าง image ไว้ดังนี้
1 | FROM httpd |
จากนั้นสั่งทำการสร้าง Image
1 | docker build -t test_change_cmd . |
จากนั้นทำการสั่งสร้าง container
1 | docker run --name test_container test_change_cmd |
ซึ่งผลลัพธ์จะเป็นดังภาพซึ่งจะเห็นว่า container ของเราทำการแสดงผล hello world Matilda ออกมา ซึ่งตรงกับที่เราสั่งไว้ และจะเห็นด้วยว่า container ของเราจะไปอยู่ในสถานะ stop ซึ่งมันก็ปกติเพราะมันทำงานคำสั่ง echo hello world Matilda เสร็จแล้ว ทำให้ container ทำการหยุดทำงาน ต่างจาก image httpd สั่งให้ใช้คำสั่ง httpd-foreground ซึ่งเป็นคำสั่งที่ทำงานแบบ infinity loop คือทำไปเรื่อยๆไม่มีจุดจบทำให้ container นั้นไม่มีวันหยุดทำงาน
ENTRYPOINT
ENTRY POINT ก็คล้ายๆกับ CMD เลยครับ คือจะให้ Container ที่สร้างจาก Image นี้ทำการ run คำสั่งอะไร ถึงตรงนี้ผมบอกเลยว่าคุณจะงงแน่นอน แต่ขอให้ลองทำครับขั้นแรกเรามาสร้าง Dockerfile โดยมีวิธีการสร้าง Image ดังนี้
1 | FROM httpd |
จากนั้นลอง build image ด้วยคำสั่งนี้ดูครับ
1 | docker build -t test_entrypoint . |
จากนั้นลองทำการ container ด้วยคำสั่งนี้ดูครับ
1 | docker run --name container_entrypoint test_entrypoint |
ซึ่งจะได้ผลลัพธ์ดังภาพ ซึ่งจะเหมือนกับ CMD เลย ซึ่งทั้งคำสั่ง CMD และ ENTRYPOINT เป็นการบอกว่าจะ Container ที่สร้างขึ้นมาจาก Image จะทำงานด้วยคำสั่งอะไร แต่มันมีข้อแตกต่างกันนิดหน่อยซึ่งจะอธิบาย ณ บัดนี้
CMD vs ENTRYPOINT
ทั้งสองทำงานคล้ายๆกันแต่แตกต่างกันนิดหน่อย เราลองมาเล่นคำสั่ง docker run ไปทีละคำสั่งครับ
1 | docker run --rm test_change_cmd |
ได้ผลลัพธ์เหมือนกัน คราวนี้มาลอง
1 | docker run --rm test_change_cmd Harupiii |
คราวนี้จะไม่เหมือนกันละ จากภาพจะเห็นว่าสั่งด้วย image ที่ใช้ CMD จะ error แต่ที่ใช้ ENTRYPOINT จะไม่ Error คราวนี้เรามาลองดูแบบละเอียดกันครับ
1 | docker run --rm test_change_cmd Harupiii |
เพื่อให้เข้าใจมากยิ่งขึ้นเรามาลองเล่นแบบนี้ดู
1 | docker run --rm test_change_cmd ls |
คราวนี้ไม่ Error ทั้งคู่ โดยฝั่ง CMD จะใช้คำสั่ง ls ซึ่งทำการ list file and directory ในปัจจุบันออกมา ส่วนฝั่ง ENTRYPOINT ยังคงเป็นการ echo คำออกมาแต่เป็นการเปลี่ยนเป็น hello world Matilda ls
แล้วจะใช้อะไร
ถ้าเอาง่ายๆก็คือ ถ้าใช้ CMD คือเราอยากให้ Container ที่ Run จาก Image นั้น run คำสั่งที่เหมือนกันไม่ต้องมีการ Customize ตัวคำสั่งที่อยาก run เช่นอย่าง image httpd นี้เขาใช้ CMD คือเขาอยากให้ Image นี้ run ด้วยคำสั่ง httpd-foreground เท่านั้น ส่วนการ config อื่นๆให้ไปทำกันที่ Environment หรือการ mount volume file config เอา แต่ถ้าใช้ ENTRYPOINT อันนี้คือเขาต้องการให้สามารถ customize คำสั่งตอน run container ได้ประมาณว่า run โดยใช้ parameter อะไรบ้างเป็นต้น โดยเขาจะใช้วิธีการสร้างไฟล์ .sh ขึ้นมาสักตัว ประมาณนี้ โดยตัวอย่างเราจะทำเป็นไฟล์ชื่อ entrypoint.sh จากนั้นในไฟล์ entrypoint ก็รับ parameter เข้ามาเพื่อให้ทำอะไรบางอย่าง เช่นตัวอย่างผมจะรับ parameter เข้ามาเพื่อทำอะไรบางอย่างที่แตกต่างกันเช่น
ไฟล์ entrypoint.sh
1 | if [ "$1" = "" ] |
อันนี้คือเราจะรับ parameter ให้กับ entrypoint.sh โดยถ้า parameter ตัวแรกที่ส่งเข้ามาเป็นคำว่า infinity จะทำการ Run แบบ infinity loop
ส่วน Dockerfile จะเป็น
1 | FROM httpd |
จากนั้นสร้าง image ด้วยคำสั่ง
1 | docker build -t test_entrypoint . |
จากนั้นลองใช้ docker run แบบต่างๆดังนี้
1 | docker run --rm test_entrypoint |
สรุป
สำหรับตอนนี้เรามาทำความเข้าใจคำสั่งสองคำสั่งคือ CMD และ ENTRYPOINT ซึ่งเราได้ลองใช้งานทั้งสองคำสั่งและความแตกต่างของแต่ละคำสั่ง ซึ่งน่าจะสามารถนำไปประยุกต์ใช้งานในการสร้าง Image ได้ในระดับที่เอาไปใช้ได้ในงานจริงแล้ว (ผมรู้แค่นี้ก็เอาไปขึ้น Production ได้แล้ว) สำหรับตอนนี้ขอจบลงเพียงเท่านี้ครับ
โปรโมท Page
ผมทำ Page บน Facebook แล้วนะครับ ใครสนใจรับการแจ้งเตือนเวลาผมอัพเดท Blog ก็ไปกดติดตามกันได้ครับ กดตามลิ้งไปได้เลย Facebook : Normal Programmer
ไม่เกี่ยวกับ Docker แต่เกี่ยวกับไอดอล
Matilda
Harupii
เพลงประกอบการเขียน Blog
เนื้อเพลงนี่แบบใช่เลย ไปร้องเพลงให้สาวฟังก็ไม่รู้จะป็นยังไง ชอบตรงการเล่นกับคำว่าหมื่นล้านเพลง เวอร์ชันต้นฉบับของพี่บิลลี่ โอแกน เวอร์ชันนี้ละมุนแบนด์เอามา cover ร้องแข่งในรายตำนานหมู่ คือร้องสด เล่นกีตาร์สด แบบ โอ้ยฟินโคตรๆ