CMD
a ENTRYPOINT
instrukce jsou dva běžně zaměňované Dockerfile
směrnice. Oba mají roli při určování příkazu, který se spustí při spuštění kontejneru.
CMD
a ENTRYPOINT
lze přepsat jednotlivě v rámci každého obrázku. Efektivní používání těchto direktiv usnadňuje používání vašeho kontejneru zkrácením délky zadaných příkazů.
Co je vstupní bod?
Podíváme se na ENTRYPOINT
nejprve při zpracování před CMD
při spuštění nového kontejneru. Vstupní bod obrázku definuje proces, který bude spuštěn při spuštění kontejneru.
Docker nastaví výchozí vstupní bod na /bin/sh -c
. To znamená, že při spuštění kontejneru skončíte v relaci shellu. U mnoha kontejnerů je více žádoucí mít ve výchozím nastavení jiné spuštění procesu. Chcete, aby bezhlavé služby začaly okamžitě pracovat.
Nastavení ENTRYPOINT
direktiva v Dockerfile
přikáže Dockeru, aby při spuštění kontejneru spustil konkrétní příkaz. Stane se procesem v popředí namísto výchozí relace shellu.
ENTRYPOINT ["date"]
Kontejner vytvořený pomocí tohoto Dockerfile
spustí date
příkaz. Jako date
není dlouhotrvající proces v popředí, kontejner se okamžitě poté opustí.
Vstupní body musí být spustitelné binární soubory nebo skripty. Pokud zadáte neplatný vstupní bod, kontejner se nespustí. Pokud používáte vlastní skript, ujistěte se, že má nastavený spustitelný bit. Oprávnění ke spuštění můžete přidat pomocí chmod +x my-script.sh
.
Přidání příkazu (CMD)
CMD
instrukce je něco jako nesprávné pojmenování. Poskytuje výchozí argumenty pro příkaz definovaný ENTRYPOINT
.
ENTRYPOINT ["date"] CMD ["+%A"]
Tento příklad vede ke spuštění kontejneru date +%A
. +%A
argument na date
zobrazuje aktuální den v týdnu (např. Monday
).
CMD
je navržen tak, aby byl přepsán. docker run
umožňuje zadat jiný příkaz pro jednotlivou instanci kontejneru:
docker run my-image +%B
Výchozí CMD
bude přepsáno +%B
, což způsobí, že kontejner zobrazí název aktuálního měsíce. Funguje to, protože vstupní bod obrázku zůstává nedotčen. CMD
je vždy připojen k ENTRYPOINT
, takže konečný příkaz se stane date +%B
.
Měli byste použít ENTRYPOINT
k definování primárního spustitelného souboru vašeho kontejneru. Použijte CMD
definovat výchozí argumenty pro tento spustitelný soubor. Bude přepsán, když je kontejner spuštěn s jinými argumenty.
Přepisy vstupních bodů
Docker můžete přinutit, aby spustil obrázek pomocí vlastního vstupního bodu. Předejte --entrypoint
příznak pro docker run
:
docker run --entrypoint /bin/sh my-image
Vstupní bod definovaný v obrázku kontejneru bude ignorován ve prospěch vámi zadaného příkazu. V našem příkladu bude místo date
spuštěna relace shellu příkaz.
Přepisování vstupních bodů by mělo být vzácným jevem. Může jít proti záměrům autora obrázku. Nastavení vlastního vstupního bodu však může být užitečné, zejména při ladění. Pokud se kontejner chová špatně, přepsání jeho vstupního bodu vám může poskytnout přístup k shellu, který byste jinak nemohli získat.
Který použít?
Pokud jste autorem obrázků, měli byste použít ENTRYPOINT
při definování toho, co bude váš kontejner provozovat. Pokud chcete poskytnout výchozí argumenty, ale očekáváte, že je uživatel přepíše, zahrňte CMD
taky.
Jako uživatel obrázku se můžete normálně držet přepsání CMD
. docker run
má transparentní podporu pro přepisy příkazů. Všechny argumenty uvedené za názvem obrázku budou interpretovány jako CMD
řetězec pro kontejner.
Režimy vstupního bodu:Shell nebo Exec
Docker ve skutečnosti podporuje dvě různé formy ENTRYPOINT
:režim exec a režim shellu. Režim Exec se vyznačuje použitím konstrukce pole pro specifikaci parametrů. V režimu shell je příkaz zadán jako jeden řetězec.
# exec mode ENTRYPOINT ["binary", "--param", "--another-param"] # shell mode ENTRYPOINT binary --param --another-param
Použití režimu shell způsobí, že váš binární soubor bude spuštěn jako podproces /bin/sh -c
. To dává vašemu vstupnímu bodu přístup k proměnným prostředí definovaným shellem.
Shell režim má však kompromisy. Nemůžete použít CMD
takže uživatelé nebudou moci vydávat přepisy. Argumenty dané docker run
bude ignorováno; váš kontejner bude vždy používat vstupní bod tak, jak je.
Vzhledem k tomu, že váš binární soubor běží v prostředí Shell, příkazy životního cyklu Dockeru jako docker stop
může fungovat nepravidelně nebo vůbec. Docker signalizuje shell zastavit, místo procesu uvnitř. Proces můžete spustit pomocí exec
abyste tomu zabránili.
ENTRYPOINT exec binary --param --another-param
Výhody přístupu Docker's Entrypoint Approach
Oddělení vstupního bodu od jeho argumentů vám pomůže skrýt složitost ve vašich kontejnerech. To je nejužitečnější, když vytváříte kontejnery nástrojů pro zapouzdření programů CLI.
Nastavte binární soubor CLI jako vstupní bod obrázku. To umožňuje uživatelům komunikovat bez opakování binárního názvu v každém příkazu.
Zvažte, zda jsme zabalili výše uvedený Dockerfile
jako date:latest
:
# default entrypoint (/bin/sh -c) docker run date:latest date +%A # with `date` as the entrypoint docker run date:latest +%A`
Nastavení vlastního vstupního bodu zkracuje příkazy a snižuje opakování. Kontejner se více specializuje vyvoláním date
automaticky. To vytváří přátelštější rozhraní pro vaše uživatele.
Přehled
ENTRYPOINT
Dockeru a CMD
pokyny jsou častým zdrojem zmatků. Jejich pojmenování maskuje jejich zamýšlené účely.
Použijte ENTRYPOINT
pro nastavení „příkazu“, který se provede při spuštění nových kontejnerů. Výchozí argumenty můžete definovat pomocí CMD
. ENTRYPOINT
a CMD
jsou zkombinovány za účelem vytvoření konečného příkazového řetězce kontejneru.
Když použijete docker run
, Docker nahradí výchozí CMD
obrázku s argumenty, které zadáte. Pokud potřebujete přepsat vstupní bod obrázku, použijte --entrypoint
vlajka.