Kakšna je razlika med CMD in ENTRYPOINT v datoteki Docker?
V datotekah Dockerfiles sta dva ukaza, ki se mi zdita podobna: CMD
in ENTRYPOINT
. Toda domnevam, da med njima obstaja (subtilna?) razlika - sicer ne bi bilo smiselno imeti dva ukaza za isto stvar.
V dokumentaciji je za CMD
navedeno
Glavni namen CMD je zagotoviti privzete nastavitve za izvajalni vsebnik.
in za ENTRYPOINT
:
ENTRYPOINT vam pomaga konfigurirati vsebnik, ki ga lahko zaženete kot izvršilno datoteko.
Kakšna je torej razlika med tema dvema ukazoma?
1478
3
Docker ima privzeto vstopno točko, ki je
/bin/sh -c
, vendar nima privzetega ukaza.Ko zaženete docker na naslednji način:
docker run -i -t ubuntu bash
je vstopna točka privzeta/bin/sh -c
, slika jeubuntu
, ukaz pabash
.Ukaz se zažene prek vstopne točke, tj. dejansko se izvede ukaz
/bin/sh -c bash
. To je Dockerju omogočilo hitro izvajanjeRUN
z zanašanjem na razčlenjevalnik lupine.Kasneje so ljudje zahtevali, da bi lahko to prilagodili, zato sta bila uvedena
ENTRYPOINT
in--entrypoint
.Vse za
ubuntu
v zgornjem primeru je ukaz in se posreduje vstopni točki. Pri uporabi navodilaCMD
je to popolnoma enako, kot če bi naredilidocker run -i -t ubuntu
. `` bo parameter vstopne točke.Enak rezultat boste dobili tudi, če namesto tega vnesete ta ukaz
docker run -i -t ubuntu
. Še vedno boste v vsebniku zagnali lupino bash, saj je v datoteki ubuntu Dockerfile določen privzeti CMD:CMD ["bash"]
Ker je vse posredovano vstopni točki, se lahko vaše slike obnašajo zelo lepo. Primer @Jiri je dober, saj prikazuje, kako uporabiti sliko kot "binarno datoteko". Če kot vstopno točko uporabite
["/bin/cat"]
in nato izvedetedocker run img /etc/passwd
, dobite,/etc/passwd
je ukaz in je posredovan vstopni točki, zato je končni rezultat izvedbe preprosto/bin/cat /etc/passwd
.Drug primer bi bil, če bi kot vstopno točko imeli katerikoli cli. Če imate na primer sliko redis, lahko namesto
docker run redisimg redis -H something -u toto get key
preprosto zaženeteENTRYPOINT ["redis", "-H", "something", "-u", "toto"]
in nato za enak rezultat izvedete takole:docker run redisimg get key
.ENTRYPOINT
določa ukaz, ki se vedno izvede ob zagonu vsebnika.Parameter
CMD
določa argumente, ki bodo posredovani ukazuENTRYPOINT
.Če želite ustvariti sliko, namenjeno določenemu ukazu, uporabite
ENTRYPOINT ["/path/dedicated_command"]
Če želite ustvariti sliko za splošne namene, lahko pustite
ENTRYPOINT
neopredeljen in uporabiteCMD ["/path/dedicated_command"]
, saj boste lahko to nastavitev prekrili z navedbo argumentov vdocker run
.Če je na primer vaša datoteka Docker:
Če zaženete sliko brez argumenta, bo ping na lokalnem gostitelju:
Če zaženete sliko z argumentom, bo slika sporočila ping na argument:
Za primerjavo, če je vaša datoteka Docker:
Če zaženete sliko brez argumenta, bo ping na lokalnem gostitelju:
Če pa zaženete sliko z argumentom, se bo zagnal argument:
Za še več podrobnosti si oglejte ta članek Briana DeHamerja: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/.
Da, to je dobro vprašanje. Ne razumem ga še v celoti, vendar:
Razumem, da je
ENTRYPOINT
binarni program, ki se izvaja. Vstopno točko lahko zamenjate z --entrypoint="".CMD je privzeti argument za vsebnik. Brez vstopne točke je privzeti argument ukaz, ki se izvede. Z vstopno točko se cmd posreduje vstopni točki kot argument. Z vstopno točko lahko posnemate ukaz.
Glavna prednost je torej ta, da lahko z vstopno točko posodi posredujete argumente (cmd). Če želite to doseči, morate uporabiti oboje:
in .
potem lahko uporabite: