การใช้งาน cmd และ entrypoint ใน Dockerfile

0
dockerfile-cmd-vs-entrypoint

ใน 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

CMD เอาไว้กำหนด default executable หรือ default arguments ให้กับ Dockerfile ของเรา เช่น

Default executable

CMD ["node", "index.js"]

Default arguments

โดยเราจะใช้งานร่วมกับ ENTRYPOINT

CMD ["index.js"]
ENTRYPOINT ["node"]

Entrypoint

ENTRYPOINT เอาไว้กำหนด default executable ซึ่งสามารถใช้ร่วมกับ CMD ได้ โดยให้ CMD เป็นตัวกำหนดค่าพารามิเตอร์ให้ ENTRYPOINT ดังตัวอย่างก่อนหน้านี้ หรือเรียกใช้งานแบบนี้ก็ได้

ENTRYPOINT ["node", "index.js"]

ตัวอย่างการใช้งาน

เรามาดูตัวอย่างการใช้งาน CMD และ ENTRYPOINT กันว่ามันทำงานยังไง โดยผมจะใช้คำสั่ง cowsay และ screenfetch เป็นตัวอย่างการแสดงผล

ตัวอย่างที่ 1

ใช้ 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._             
                `""""    

ตัวอย่างที่ 2

เรามาลองใช้งาน 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 |
                ||     ||

ตัวอย่างที่ 3

เรามาลองใช้งาน 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

ทิ้งคำตอบไว้

Please enter your comment!
Please enter your name here

2 + 16 =