ใน Dockerfile จะมีคำสั่งสองคำสั่งที่ทำงานคล้ายกันมากคือ CMD และ ENTRYPOINT ซึ่งโดยวิธีใช้ทั้งสองอันจะเป็นการเรียกชุดคำสั่ง (command หรือ executables) สุดท้ายก่อนที่ docker จะสร้าง container ขึ้นมา
ทั้ง cmd และ entrypoint มีวิธีการเขียนดังนี้
CMD ["executable", "arg1", "arg2"]
ENTRYPOINT ["executable", "arg1", "arg2"]
เวลาตอนสร้าง Container ขึ้นมามันก็จะถูกเรียกใช้แบบนี้
CMD executable arg1 arg2
ENTRYPOINT executable arg1 arg2
CMD เอาไว้กำหนด default executable หรือ default arguments ให้กับ Dockerfile ของเรา เช่น
CMD ["node", "index.js"]
โดยเราจะใช้งานร่วมกับ ENTRYPOINT
CMD ["index.js"]
ENTRYPOINT ["node"]
ENTRYPOINT เอาไว้กำหนด default executable ซึ่งสามารถใช้ร่วมกับ CMD ได้ โดยให้ CMD เป็นตัวกำหนดค่าพารามิเตอร์ให้ ENTRYPOINT ดังตัวอย่างก่อนหน้านี้ หรือเรียกใช้งานแบบนี้ก็ได้
ENTRYPOINT ["node", "index.js"]
เรามาดูตัวอย่างการใช้งาน CMD และ ENTRYPOINT กันว่ามันทำงานยังไง โดยผมจะใช้คำสั่ง cowsay และ screenfetch เป็นตัวอย่างการแสดงผล
ใช้ CMD กำหนด default executable ให้ทำการสร้างไฟล์ชื่อ Dockerfile-cmd
แล้วใส่คำสั่งดังนี้
FROM debian:jessie-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
cowsay \
screenfetch && \
rm -rf /var/lib/apt/lists/*
ENV PATH "$PATH:/usr/games"
CMD ["cowsay", "Yo, CMD !!"]
สร้าง Image: docker build -t demo:cmd -f Dockerfile-cmd .
สร้าง Container: docker run --rm demo:cmd
เราจะได้ผลลัพธ์ดังนี้
$ docker run --rm demo:cmd
____________
< Yo, CMD !! >
------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
อย่างไรก็ตามเราสามารถใส่ command อันใหม่แทนได้ โดยพิมพ์ต่อท้าย docker run --rm demo:cmd screenfetch -E
เราจะได้ผลลัพธ์ดังนี้
$ docker run --rm demo:cmd screenfetch -E
_,met$$$$$gg. @0cc9e5da8bca
,g$$$$$$$$$$$$$$$P. OS: Debian
,g$$P"" """Y$$.". Kernel: x86_64 Linux 4.15.0-72-generic
,$$P' `$$$. Uptime: 4h 0m
',$$P ,ggs. `$$b: Packages: 106
`d$$' ,$P"' . $$$ Shell:
$$P d$' , $$P CPU: Intel Core i5-8250U CPU @ 3.4GHz
$$: $$. - ,d$$' RAM: 4334MB / 7873MB
$$\; Y$b._ _,d$P'
Y$$. `.`"Y$$$$P"'
`$$b "-.__
`Y$$
`Y$$.
`$$b.
`Y$$b.
`"Y$b._
`""""
เรามาลองใช้งาน ENTRYPOINT ในการกำหนด default executable กัน ให้สร้างไฟล์ชื่อ Dockerfile-entry
แล้วพิมพ์ดังนี้
FROM debian:jessie-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
cowsay \
screenfetch && \
rm -rf /var/lib/apt/lists/*
ENV PATH "$PATH:/usr/games"
ENTRYPOINT ["cowsay", "Yo, Entrypoint!!"]
สร้าง Image: docker build -t demo:entry -f Dockerfile-entry .
สร้าง Container: docker run --rm demo:entry
เราจะได้ผลลัพธ์ดังนี้
$ docker run --rm demo:entry
__________________
< Yo, Entrypoint!! >
------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
แต่คราวนี้ถ้าเราอยากจะใส่ command ชุดใหม่ไปแทนแบบ CMD มันจะไม่สามารถทำได้ แต่จะเป็นการส่งค่า arguments ไปแทน เช่น docker run demo:entry screenfetch -E
เราจะได้ผลลัพธ์ดังนี้
$ docker run --rm demo:entry screenfetch -E
_________________________________
< Yo, Entrypoint!! screenfetch -E >
---------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
เรามาลองใช้งาน ENTRYPOINT และ CMD ด้วยกัน ซึ่งการใช้งานแบบนี้หาก ENTRYPOINT ถูกกำหนดแล้ว CMD จะถูกมองให้เป็น arguments ไปยัง ENTRYPOINT ทันที ให้สร้างไฟล์ชื่อ Dockerfile-cmd-entry
แล้วพิมพ์ดังนี้
FROM debian:jessie-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
cowsay \
screenfetch && \
rm -rf /var/lib/apt/lists/*
ENV PATH "$PATH:/usr/games"
CMD ["Yo, CMD!!"]
ENTRYPOINT ["cowsay", "Yo, Entrypoint!!"]
สร้าง Image: docker build -t demo:cmd-entry -f Dockerfile-cmd-entry .
สร้าง Container: docker run --rm demo:cmd-entry
เราจะได้ผลลัพธ์ดังนี้
$ docker run --rm demo:cmd-entry
____________________________
< Yo, Entrypoint!! Yo, CMD!! >
----------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
ซึ่งเราสามารถแทนค่า arguments ที่กำหนดไว้ใน CMD ได้ง่ายๆ ดังนี้ docker run --rm demo:cmd-entry Overriding arg passed in cmd
เราจะได้ผลลัพธ์ดังนี้
$ docker run --rm demo:cmd-entry Overriding arg passed in cmd
________________________________________
/ Yo, Entrypoint!! Overriding arg passed \
\ in cmd /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
ก็ลองไปปรับใช้กันดูนะครับสำหรับ CMD และ ENTRYPOINT
Happy docker 🙂
Thanks: dev.to/lasatadevi/docker-cmd-vs-entrypoint-34e0