Utilizzo delle istruzioni ENTRYPOINT e CMD nel Dockerfile

Se hai mai avuto bisogno di eseguire uno o due comandi nel tuo container Docker all’avvio, questo tutorial fa al caso tuo. Utilizzando il Dockerfile le istruzioni ENTRYPOINT e CMD, puoi eseguire quanti comandi di avvio desideri.

In questo tutorial imparerai come utilizzare le istruzioni ENTRYPOINT e CMD per eseguire comandi di avvio in un Dockerfile e capirai le differenze tra di esse.

Prerequisiti

Dato che questo tutorial sarà una dimostrazione pratica, assicurati di avere quanto segue:

  • A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
  • Docker Desktop – Questo tutorial utilizza Docker Desktop v3.3.1.

Creazione di un Dockerfile

Prima di poter eseguire comandi di avvio del container Docker, devi prima creare un Dockerfile. Un Dockerfile è un documento di testo che contiene un elenco di comandi per creare container, immagini Docker e determina come viene creata un’immagine Docker.

1. In primo luogo, apri PowerShell come amministratore.

2. Crea una nuova cartella per salvare il Dockerfile e tutti i file associati che questo tutorial utilizzerà e cambia a quella directory. Questo tutorial sta utilizzando ~/docker.

mkdir ~/docker
cd docker

3. Ora, crea un file di testo vuoto chiamato Dockerfile con il seguente comando.

cd > Dockerfile

In alternativa, puoi creare un Dockerfile con il seguente comando se sei su Linux o Mac OS.

touch Dockerfile

4. Infine, aggiungi il seguente contenuto nel Dockerfile

FROM ubuntu:20.04

Ora hai creato un Dockerfile che sarà presto completo!

Costruzione di un’immagine Docker

Ora che hai creato il tuo Dockerfile, devi creare un’immagine Docker per eseguire i comandi scritti nelle istruzioni ENTRYPOINT e CMD del tuo Dockerfile. Un modo per creare un’immagine è utilizzare il build comando.

Mentre sei nella directory ~/docker, esegui il seguente comando. Il comando qui sotto crea un’immagine Docker chiamata demo (-t demo) dal Dockerfile in ~/docker specificando la directory di lavoro corrente (.).

docker build -t demo .
Building a Docker Image

Esecuzione di un Container Docker

Dopo aver creato l’immagine Docker, avrai bisogno di un container per eseguire l’immagine Docker che eseguirà i comandi dalle istruzioni ENTRYPOINT e CMD del Dockerfile.

Per eseguire un contenitore Docker, invoca il comando run per creare uno strato di contenitore scrivibile sopra l’immagine Docker (demo). Nell’esempio seguente si utilizza il parametro -it per connettersi interattivamente al contenitore in modo da poter visualizzare l’output di esempio.

docker run -it demo
Running a Docker Container

Forma Exec vs. Shell

Quando inizi a lavorare con un Dockerfile e capisci come eseguire i comandi di avvio, potresti imbatterti in due metodi diversi per definire questi comandi. Ogni metodo invocherà i comandi, ma lo farà in modo leggermente diverso.

Quando Docker esegue i comandi, può farlo direttamente chiamando exec o attraverso la shell del contenitore (/bin/sh -c su Linux o cmd /S /C su Windows) chiamato shell.

Noterai che i comandi eseguiti tramite exec hanno un’istruzione seguita dagli eseguibili da invocare seguiti da uno o più argomenti da riga di comando, come mostrato di seguito.

ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]

Scrivere comandi in forma di shell, d’altra parte, non richiede di avvolgere i comandi tra parentesi quadre, come mostrato di seguito.

ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"

Se non specifici un argomento per CMD, Docker eseguirà sempre il comando in forma di exec, ad es. CMD <command>.

Se stai iniziando solo ora, differenziare tra queste due invocazioni di comando non avrà molta importanza, ma man mano che diventi più esperto, presto vedrai vantaggi e svantaggi per ciascuna.

Esecuzione dei comandi di avvio

Ora entriamo nel vivo di questo tutorial e mettiamo le mani in pasta esaminando alcuni esempi di esecuzione di comandi di avvio all’interno di un Dockerfile tramite le istruzioni ENTRYPOINT e CMD.

1. Apri il Dockerfile che hai creato in precedenza nel tuo editor di testo preferito.

2. Copia e incolla i contenuti dell’esempio di Dockerfile nel tuo Dockerfile, come mostrato di seguito, e salvalo.

Questo Dockerfile crea un livello utilizzando ubuntu:20.04 come immagine di base. Quindi dice a Docker di invocare il comando echo passandogli l’argomento Hello world per entrambe le istruzioni del Dockerfile CMD e ENTRYPOINT utilizzando le forme exec e shell.

FROM ubuntu:20.04
# Istruzione CMD
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world"      # Shell Form
# Istruzione ENTRYPOINT
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world"      # Shell Form

3. Mentre ti trovi nella directory ~/docker, costruisci la nuova immagine eseguendo docker build e chiamala demo. Il comando sottostante etichetta l’immagine come demo e cerca un Dockerfile nella directory di lavoro corrente (.).

docker build -t demo .
Building a Docker image with docker build

4. Ora, esegui un container utilizzando l’immagine poi esegui un container Docker basato sull’immagine Docker creata in precedenza. Vedrai ora che il container restituisce Hello world proveniente dall’istruzione CMD fornita nel Dockerfile.

docker run -it demo
Running a Docker container with docker run

Utilizzo delle Variabili in un Dockerfile

A volte potresti non conoscere esattamente gli argomenti della riga di comando da passare al comando in anticipo. Gli argomenti da passare a un comando sono esposti solo durante l’esecuzione. Invece di assegnare staticamente gli argomenti del comando, puoi acquisire e passare quegli argomenti ai comandi con le variabili.

Puoi utilizzare solo le variabili di Dockerfile nella forma shell. Docker non supporta le variabili nei comandi invocati tramite la forma exec.

Apri nuovamente il Dockerfile nel tuo editor di testo preferito, sostituisci tutto all’interno con la seguente serie di comandi e salvalo.

Noterai che questa volta il Dockerfile utilizza le variabili di ambiente e le mostra utilizzando ENV. Nell’esempio sottostante, il Dockerfile definisce una variabile di ambiente chiamata name con un valore di friend. Una volta creata, questa variabile di ambiente viene quindi richiamata tramite $name.

Quando Docker esegue un container basato su questo Dockerfile, invocherà il comando echo e passerà l’argomento Welcome, friend.

FROM ubuntu:20.04
ENV name friend

CMD echo "Welcome, $name"
# o
## ENTRYPOINT echo "Benvenuto, $name"

Ora, crea nuovamente l’immagine Docker ed esegui il container fornendo facoltativamente un nome tag di shellform. Noterai che Docker ha invocato il comando echo e ha restituito l’output previsto.

Building a Docker Image (shellform) and Running a Docker Container

Combinando le istruzioni ENTRYPOINT e CMD del Dockerfile

La maggior parte delle volte, invocherai comandi di avvio sia nell’istruzione CMD che nell’istruzione ENTRYPOINT. Dopotutto, puoi invocare quanti comandi desideri utilizzando ciascun metodo. Ma puoi anche invocare un singolo comando e “aggiungerci” utilizzando entrambe le istruzioni.

Basandoci sugli esempi precedenti, forse hai un Dockerfile che assomiglia all’esempio sottostante. Come è, se crei un’immagine e avvii un contenitore da quell’immagine, Docker invocherà il comando echo e restituirà Hello.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]

Forse hai un altro argomento che desideri passare al comando echo, ma non subito. Forse vorresti farlo più avanti nel Dockerfile. Chiamando l’istruzione CMD senza un comando, puoi farlo.

Quando specifici un comando da eseguire tramite l’istruzione ENTRYPOINT seguita dall’istruzione CMD, Docker assume automaticamente che il valore passato a CMD sia un argomento; non un comando.

Ora, aggiungi un riferimento all’istruzione CMD senza un comando, solo un argomento chiamato world, come mostrato di seguito.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]

La combinazione di istruzioni dovrebbe sempre essere scritta in forma esecutiva a causa del suo comportamento “simile a un array” di specificare i valori individualmente separati da virgole invece che tutti in una sola stringa.

Dopo aver creato l’immagine e avviato il contenitore dall’immagine, puoi vedere che invece di due righe di output (Hello e world), Docker restituisce solo una, il che significa che viene invocato solo un singolo comando echo.

Building a Docker Image (demo3) and Running a Docker Container

Conclusione

Dovresti ora avere una buona comprensione dell’esecuzione dei comandi di avvio del contenitore Docker tramite le istruzioni CMD e ENTRYPOINT nel Dockerfile. Ogni istruzione è un po’ diversa ma svolge lo stesso compito e può anche essere usata insieme.

Puoi pensare a uno scenario in cui preferiresti utilizzare CMD invece di ENTRYPOINT per eseguire un comando di avvio?

Source:
https://adamtheautomator.com/dockerfile-entrypoint/