Docker
Dockerfiles
Ricerca…
introduzione
I file Docker sono file utilizzati per creare in modo programmatico immagini Docker. Ti consentono di creare in modo rapido e riproducibile un'immagine Docker e quindi sono utili per la collaborazione. I file Docker contengono istruzioni per la creazione di un'immagine Docker. Ogni istruzione è scritta su una riga e viene data nella forma <INSTRUCTION><argument(s)>
. I Dockerfile sono usati per costruire immagini Docker usando il comando di docker build
.
Osservazioni
I Dockerfiles sono nella forma:
# This is a comment
INSTRUCTION arguments
- I commenti iniziano con
#
- Le istruzioni sono solo in maiuscolo
- La prima istruzione di un Dockerfile deve essere
FROM
per specificare l'immagine di base
Durante la creazione di un Dockerfile, il client Docker invierà un "build context" al daemon Docker. Il contesto di costruzione include tutti i file e le cartelle nella stessa directory del file Docker. COPY
operazioni COPY
e ADD
possono solo utilizzare file da questo contesto.
Alcuni file Docker possono iniziare con:
# escape=`
Questo è usato per istruire il parser Docker per usare `
come carattere di escape invece di \
. Questo è utile soprattutto per i file di Windows Docker.
HelloWorld Dockerfile
Un Dockerfile minimale si presenta così:
FROM alpine
CMD ["echo", "Hello StackOverflow!"]
Ciò istruirà Docker per creare un'immagine basata su Alpine ( FROM
), una distribuzione minima per i contenitori e per eseguire un comando specifico ( CMD
) quando si esegue l'immagine risultante.
Costruisci ed eseguilo:
docker build -t hello .
docker run --rm hello
Questo produrrà:
Hello StackOverflow!
Copia di file
Per copiare file dal contesto di costruzione in un'immagine Docker, usa l'istruzione COPY
:
COPY localfile.txt containerfile.txt
Se il nome del file contiene spazi, utilizza la sintassi alternativa:
COPY ["local file", "container file"]
Il comando COPY
supporta i caratteri jolly. Può essere usato ad esempio per copiare tutte le immagini nella cartella images/
:
COPY *.jpg images/
Nota: in questo esempio, le images/
potrebbero non esistere. In questo caso, Docker lo creerà automaticamente.
Esporre una porta
Dichiarare porte esposte da un Dockerfile utilizzare la EXPOSE
istruzione:
EXPOSE 8080 8082
L'impostazione delle porte esposte può essere sovrascritta dalla riga di comando Docker, ma è buona norma impostarle in modo esplicito nel Dockerfile in quanto aiuta a capire cosa fa un'applicazione.
Dockerfiles migliori pratiche
Raggruppare le operazioni comuni
Docker crea immagini come una raccolta di livelli. Ogni livello può solo aggiungere dati, anche se questi dati indicano che un file è stato cancellato. Ogni istruzione crea un nuovo livello. Per esempio:
RUN apt-get -qq update
RUN apt-get -qq install some-package
Ha un paio di aspetti negativi:
- Creerà due livelli, producendo un'immagine più grande.
- L'utilizzo
apt-get update
da solo in un'istruzioneRUN
causa problemi di memorizzazione nella cache e successivamente le istruzioni diapt-get install
potrebbero non riuscire . Si supponga di modificare in seguitoapt-get install
aggiungendo pacchetti aggiuntivi, quindi la finestra mobile interpreta le istruzioni iniziali e modificate come identiche e riutilizza la cache dai passaggi precedenti. Di conseguenza il comandoapt-get update
non viene eseguito perché la sua versione cache viene utilizzata durante la compilazione.
Invece, usa:
RUN apt-get -qq update && \
apt-get -qq install some-package
come questo produce solo un livello.
Cita il manutentore
Questa è solitamente la seconda riga del Dockerfile. Indica chi è responsabile e sarà in grado di aiutare.
LABEL maintainer John Doe <[email protected]>
Se lo salti, non romperà la tua immagine. Ma non aiuterà neanche i tuoi utenti.
Sii conciso
Tieni corto il tuo Dockerfile. Se è necessaria una configurazione complessa, prendere in considerazione l'utilizzo di uno script dedicato o l'impostazione di immagini di base.
Istruzioni per l'utente
USER daemon
L'istruzione USER
imposta il nome utente o l'UID da utilizzare quando si esegue l'immagine e per tutte le istruzioni RUN
, CMD
e ENTRYPOINT
che seguono nel file Dockerfile
.
Istruzione WORKDIR
WORKDIR /path/to/workdir
L'istruzione WORKDIR
imposta la directory di lavoro per tutte le istruzioni RUN
, CMD
, ENTRYPOINT
, COPY
e ADD
che seguono nel Dockerfile. Se il WORKDIR
non esiste, verrà creato anche se non viene utilizzato in alcuna istruzione Dockerfile
successiva.
Può essere utilizzato più volte nell'unico file Dockerfile
. Se viene fornito un percorso relativo, sarà relativo al percorso della precedente istruzione WORKDIR
. Per esempio:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
L'output del comando pwd
finale in questo Dockerfile
sarebbe /a/b/c
.
L'istruzione WORKDIR
può risolvere le variabili di ambiente precedentemente impostate tramite ENV
. È possibile utilizzare solo le variabili di ambiente impostate in modo esplicito nel file Dockerfile
. Per esempio:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
L'output del comando pwd
finale in questo Dockerfile sarebbe /path/$DIRNAME
VOLUME Istruzione
VOLUME ["/data"]
L'istruzione VOLUME
crea un punto di montaggio con il nome specificato e lo contrassegna come contenente volumi montati esternamente dall'host nativo o da altri contenitori. Il valore può essere un array JSON, VOLUME ["/var/log/"]
o una stringa semplice con più argomenti, come VOLUME /var/log
o VOLUME /var/log /var/db
. Per ulteriori informazioni / esempi e istruzioni di montaggio tramite il client Docker, fare riferimento a Condividi directory tramite la documentazione Volumi.
Il comando di docker run
inizializza il volume appena creato con tutti i dati esistenti nella posizione specificata all'interno dell'immagine di base. Ad esempio, considera il seguente snippet Dockerfile:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
Questo file Docker produce un'immagine che fa girare la finestra mobile, per creare un nuovo punto di montaggio su / myvol e copiare il file di benvenuto nel volume appena creato.
Nota: se alcuni passi di costruzione modificano i dati all'interno del volume dopo che è stato dichiarato, tali modifiche verranno scartate.
Nota: l'elenco viene analizzato come un array JSON, il che significa che è necessario utilizzare virgolette (") attorno a words not single-quotes (').
Istruzione di COPY
COPY
ha due forme:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
L'istruzione COPY
copia nuovi file o directory da <src>
e li aggiunge al filesystem del contenitore nel percorso <dest>
.
È possibile specificare più risorse <src>
ma devono essere relative alla directory di origine che viene creata (il contesto della generazione).
Ogni <src>
può contenere caratteri jolly e la corrispondenza verrà effettuata utilizzando le regole del filepath.Match
di Go. Per esempio:
COPY hom* /mydir/ # adds all files starting with "hom"
COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>
è un percorso assoluto o un percorso relativo a WORKDIR
, in cui la sorgente verrà copiata all'interno del contenitore di destinazione.
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
Tutti i nuovi file e directory vengono creati con un UID e GID di 0.
Nota: se si crea usando stdin ( docker build - < somefile
), non esiste un contesto di build, quindi non è possibile utilizzare COPY
.
COPY
rispetta le seguenti regole:
Il percorso
<src>
deve essere all'interno del contesto della build; non è possibileCOPY
../qualcosa / qualcosa, poiché il primo passaggio di una build finestra mobile consiste nell'inviare la directory di contesto (e le sottodirectory) al daemon docker.Se
<src>
è una directory, vengono copiati tutti i contenuti della directory, inclusi i metadati del filesystem. Nota: la directory non viene copiata, ma solo il suo contenuto.Se
<src>
è un qualsiasi altro tipo di file, viene copiato individualmente insieme ai suoi metadati. In questo caso, se<dest>
termina con una barra finale, verrà considerata una directory e il contenuto di<src>
verrà scritto in<dest>/base(<src>)
.Se vengono specificate più risorse
<src>
, direttamente o a causa dell'uso di un carattere jolly, allora<dest>
deve essere una directory e deve terminare con una barra/
.Se
<dest>
non termina con una barra finale, verrà considerato un file normale e il contenuto di<src>
verrà scritto in<dest>
.Se
<dest>
non esiste, viene creato insieme a tutte le directory mancanti nel suo percorso.
Le istruzioni ENV e ARG
ENV
ENV <key> <value>
ENV <key>=<value> ...
L'istruzione ENV
imposta la variabile di ambiente <key>
sul valore. Questo valore sarà nell'ambiente di tutti i comandi "discendenti" Dockerfile e può essere sostituito anche in linea in molti.
L'istruzione ENV
ha due forme. Il primo modulo, ENV <key> <value>
, imposterà una singola variabile su un valore. L'intera stringa dopo il primo spazio verrà considerata come <value>
, inclusi caratteri come spazi e virgolette.
Il secondo modulo, ENV <key>=<value> ...
, consente di impostare più variabili contemporaneamente. Si noti che il secondo modulo utilizza il segno di uguale (=) nella sintassi, mentre il primo modulo non lo fa. Come l'analisi della riga di comando, le virgolette e le barre retroverse possono essere utilizzate per includere spazi all'interno dei valori.
Per esempio:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
e
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
produrrà gli stessi risultati netti nel contenitore finale, ma la prima forma è preferita perché produce un singolo livello di cache.
Le variabili di ambiente impostate utilizzando ENV
permangono quando viene eseguito un contenitore dall'immagine risultante. È possibile visualizzare i valori utilizzando il controllo finestra mobile e modificarli utilizzando la docker run --env <key>=<value>
.
ARG
Se non desideri mantenere l'impostazione, usa invece ARG
. ARG
imposterà gli ambienti solo durante la compilazione. Ad esempio, impostazione
ENV DEBIAN_FRONTEND noninteractive
potrebbe confondere gli utenti apt-get
su un'immagine basata su Debian quando entrano nel contenitore in un contesto interattivo tramite docker exec -it the-container bash
.
Invece, usa:
ARG DEBIAN_FRONTEND noninteractive
In alternativa, puoi anche impostare un valore per un singolo comando usando solo:
RUN <key>=<value> <command>
ESPORTAZIONE
EXPOSE <port> [<port>...]
L'istruzione EXPOSE
informa Docker che il contenitore è in ascolto sulle porte di rete specificate in fase di runtime. EXPOSE
NON rende accessibili le porte del contenitore all'host. Per fare ciò, è necessario utilizzare il flag -p
per pubblicare un intervallo di porte o il flag -P
per pubblicare tutte le porte esposte. Questi flag vengono utilizzati nella docker run [OPTIONS] IMAGE [COMMAND][ARG...]
per esporre la porta all'host. È possibile esporre un numero di porta e pubblicarlo esternamente con un altro numero.
docker run -p 2500:80 <image name>
Questo comando creerà un contenitore con il nome <image> e rilegherà la porta del contenitore 80 alla porta 2500 della macchina host.
Per impostare il reindirizzamento della porta sul sistema host, vedere l'uso -P
. La funzione di rete Docker supporta la creazione di reti senza la necessità di esporre le porte all'interno della rete, per informazioni dettagliate consultare la panoramica di questa funzionalità).
Istruzione LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
L'istruzione LABEL
aggiunge metadati a un'immagine. A LABEL
è una coppia chiave-valore. Per includere spazi all'interno di un valore LABEL
, utilizza virgolette e barre retroverse come faresti nell'analisi della riga di comando. Alcuni esempi di utilizzo:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
Un'immagine può avere più di un'etichetta. Per specificare più etichette, Docker consiglia di combinare le etichette in un'unica istruzione LABEL
laddove possibile. Ogni istruzione LABEL
produce un nuovo livello che può causare un'immagine inefficiente se si utilizzano molte etichette. Questo esempio si traduce in un singolo livello di immagine.
LABEL multi.label1="value1" multi.label2="value2" other="value3"
Quanto sopra può anche essere scritto come:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Le etichette sono additive incluse le LABEL
nelle immagini FROM
. Se Docker rileva un'etichetta / chiave già esistente, il nuovo valore sostituisce tutte le etichette precedenti con chiavi identiche.
Per visualizzare le etichette di un'immagine, utilizzare il comando di controllo finestra mobile.
"Labels": {
"com.example.vendor": "ACME Incorporated"
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
},
Istruzione CMD
L'istruzione CMD
ha tre forme:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
Ci può essere solo un'istruzione CMD
in un Dockerfile
. Se si elencano più di un CMD
allora solo l'ultimo CMD
avrà effetto.
Lo scopo principale di un CMD
è di fornire i valori predefiniti per un contenitore in esecuzione. Questi valori predefiniti possono includere un eseguibile oppure possono omettere l'eseguibile, nel qual caso è necessario specificare anche un'istruzione ENTRYPOINT
.
Nota: se CMD
viene utilizzato per fornire argomenti predefiniti per l'istruzione ENTRYPOINT
, entrambe le istruzioni CMD
e ENTRYPOINT
devono essere specificate con il formato di array JSON.
Nota: il modulo exec viene analizzato come un array JSON, il che significa che è necessario utilizzare virgolette (") attorno a words not single-quotes (').
Nota: a differenza del modulo shell, il modulo exec non richiama una shell di comando. Ciò significa che la normale elaborazione della shell non avviene. Ad esempio, CMD [ "echo", "$HOME" ]
non eseguirà la sostituzione delle variabili su $HOME
. Se si desidera l'elaborazione della shell, utilizzare la forma della shell o eseguire direttamente una shell, ad esempio: CMD [ "sh", "-c", "echo $HOME" ]
.
Quando viene utilizzato nei formati shell o exec, l'istruzione CMD
imposta il comando da eseguire quando si esegue l'immagine.
Se si utilizza il modulo shell della CMD
, il comando verrà eseguito in /bin/sh -c
:
FROM ubuntu
CMD echo "This is a test." | wc -
Se si desidera eseguire il comando senza shell, è necessario esprimere il comando come array JSON e fornire il percorso completo dell'eseguibile. Questa forma di matrice è il formato preferito di CMD
. Eventuali parametri aggiuntivi devono essere espressi singolarmente come stringhe nell'array:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
Se si desidera che il contenitore esegua sempre lo stesso eseguibile, è consigliabile utilizzare ENTRYPOINT
in combinazione con CMD
. Vedi ENTRYPOINT
.
Se l'utente specifica gli argomenti sulla finestra mobile, questi sovrascriveranno il valore predefinito specificato in CMD
.
Nota: non confondere RUN
con CMD
. RUN
esegue effettivamente un comando al momento della creazione dell'immagine e impegna il risultato; CMD
non esegue nulla al momento della compilazione, ma specifica il comando previsto per l'immagine.
Istruzione MAINTAINER
MAINTAINER <name>
L'istruzione MAINTAINER
consente di impostare il campo Autore delle immagini generate.
NON USARE LA DIRETTIVA MAINTAINER
Secondo la documentazione ufficiale di Docker, l'istruzione MAINTAINER
è deprecata. Invece, si dovrebbe usare l'istruzione LABEL
per definire l'autore delle immagini generate. L'istruzione LABEL
è più flessibile, consente di impostare i metadati e può essere facilmente visualizzata con il comando docker inspect
.
LABEL maintainer="[email protected]"
Dall'istruzione
FROM <image>
O
FROM <image>:<tag>
O
FROM <image>@<digest>
L'istruzione FROM
imposta l'immagine di base per le istruzioni successive. Come tale, un Dockerfile valido deve avere FROM
come prima istruzione. L'immagine può essere qualsiasi immagine valida - è particolarmente facile iniziare tirando un'immagine dai repository pubblici.
FROM
deve essere la prima istruzione non commentata nel Dockerfile.
FROM
può apparire più volte all'interno di un singolo Dockerfile per creare più immagini. Basta prendere nota dell'ultimo ID immagine emesso dal commit prima di ogni nuovo comando FROM
.
I valori del tag o digest sono opzionali. Se si omette uno di essi, il builder assume un valore più recente per impostazione predefinita. Il builder restituisce un errore se non può corrispondere al valore del tag.
Istruzione RUN
RUN
ha 2 forme:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)
L'istruzione RUN
eseguirà tutti i comandi in un nuovo livello sopra l'immagine corrente e confermerà i risultati. L'immagine commessa risultante verrà utilizzata per il passaggio successivo nel file Dockerfile
.
La stratificazione delle istruzioni RUN
e la generazione dei commit sono conformi ai concetti chiave di Docker, in cui i commit sono convenienti e i contenitori possono essere creati da qualsiasi punto nella cronologia di un'immagine, proprio come il controllo del codice sorgente.
Il modulo exec consente di evitare il munging della stringa di shell e di eseguire comandi RUN
utilizzando un'immagine di base che non contiene l'eseguibile shell specificato.
La shell di default per il modulo shell può essere modificata usando il comando SHELL
.
Nel modulo della shell è possibile utilizzare un \
(backslash) per continuare una singola istruzione RUN
sulla riga successiva. Ad esempio, considera queste due linee:
RUN /bin/bash -c 'source $HOME/.bashrc ;\
echo $HOME'
Insieme sono equivalenti a questa singola riga:
RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'
Nota: per utilizzare una shell diversa, diversa da '/ bin / sh', utilizzare il modulo exec che passa nella shell desiderata. Ad esempio, RUN ["/bin/bash", "-c", "echo hello"]
Nota: il modulo exec viene analizzato come un array JSON, il che significa che è necessario utilizzare virgolette ( “
) attorno a words not single-quotes ( '
).
Nota: a differenza del modulo shell, il modulo exec non richiama una shell di comando. Ciò significa che la normale elaborazione della shell non avviene. Ad esempio, RUN [ "echo", "$HOME" ]
non eseguirà la sostituzione delle variabili su $HOME
. Se si desidera l'elaborazione della shell, utilizzare il modulo di shell o eseguire direttamente una shell, ad esempio: RUN [ "sh", "-c", "echo $HOME" ]
.
Nota: nel modulo JSON, è necessario evitare i backslash. Questo è particolarmente rilevante su Windows in cui il backslash è il separatore del percorso. La seguente riga verrebbe altrimenti trattata come una forma di shell a causa di non essere JSON valido e non riuscire in modo inaspettato: RUN ["c:\windows\system32\tasklist.exe"]
La sintassi corretta per questo esempio è: RUN ["c:\\windows\\system32\\tasklist.exe"]
La cache per le istruzioni RUN
non viene invalidata automaticamente durante la build successiva. La cache per un'istruzione come RUN apt-get dist-upgrade -y
verrà riutilizzata durante la build successiva. La cache per le istruzioni RUN
può essere invalidata utilizzando il flag --no-cache, ad esempio build docker --no-cache.
Per ulteriori informazioni, consultare la guida Best Practices di Dockerfile.
La cache per istruzioni RUN
può essere invalidata dalle istruzioni ADD
. Vedi sotto per i dettagli.
ONBUILD Istruzioni
ONBUILD [INSTRUCTION]
L'istruzione ONBUILD
aggiunge all'immagine un'istruzione trigger da eseguire in un secondo momento, quando l'immagine viene utilizzata come base per un'altra build. Il trigger verrà eseguito nel contesto della build downstream, come se fosse stato inserito immediatamente dopo l'istruzione FROM
nel Dockerfile downstream.
Qualsiasi istruzione di costruzione può essere registrata come trigger.
Ciò è utile se si sta costruendo un'immagine che verrà utilizzata come base per creare altre immagini, ad esempio un ambiente di sviluppo dell'applicazione o un demone che può essere personalizzato con una configurazione specifica dell'utente.
Ad esempio, se l'immagine è un costruttore di applicazioni Python riutilizzabile, richiederà l'aggiunta di un codice sorgente dell'applicazione in una directory specifica e potrebbe richiedere la creazione di uno script di generazione. Non puoi semplicemente chiamare ADD
e RUN
ora, perché non hai ancora accesso al codice sorgente dell'applicazione, e sarà diverso per ogni build dell'applicazione. Potresti semplicemente fornire agli sviluppatori di applicazioni un dockerfile di tipo standard per copiare e incollare nella loro applicazione, ma questo è inefficiente, soggetto a errori e difficile da aggiornare perché si mescola con il codice specifico dell'applicazione.
La soluzione è utilizzare ONBUILD
per registrare le istruzioni avanzate da eseguire più tardi, durante la fase di costruzione successiva.
Ecco come funziona:
Quando incontra un'istruzione ONBUILD
, il builder aggiunge un trigger ai metadati dell'immagine che viene creata. L'istruzione non influisce altrimenti sulla build corrente.
Alla fine della compilazione, un elenco di tutti i trigger è archiviato nel manifest dell'immagine, sotto la chiave OnBuild. Possono essere ispezionati con il comando di docker inspect
. Successivamente l'immagine può essere usata come base per una nuova build, usando l'istruzione FROM
. Come parte dell'elaborazione dell'istruzione FROM
, il builder downstream cerca i trigger ONBUILD
e li esegue nello stesso ordine in cui sono stati registrati. Se uno dei trigger fallisce, l'istruzione FROM
viene interrotta, il che a sua volta causa il fallimento della build. Se tutti i trigger hanno esito positivo, l'istruzione FROM
completata e la generazione continua come al solito.
I trigger vengono cancellati dall'immagine finale dopo essere stati eseguiti. In altre parole, non sono ereditati da build "grand-children".
Ad esempio potresti aggiungere qualcosa come questo:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
Avviso: concatenare ONBUILD
istruzioni ONBUILD
utilizzando ONBUILD
ONBUILD
non è consentito.
Avvertenza: l'istruzione ONBUILD
potrebbe non attivare le istruzioni FROM
o MAINTAINER
.
Istruzione STOPSIGNAL
STOPSIGNAL signal
L'istruzione STOPSIGNAL
imposta il segnale di chiamata di sistema che verrà inviato al contenitore per uscire. Questo segnale può essere un numero non firmato valido che corrisponde a una posizione nella tabella syscall del kernel, ad esempio 9, o un nome di segnale nel formato SIGNAME, ad esempio SIGKILL.
Istruzione HEALTHCHECK
L'istruzione HEALTHCHECK
ha due forme:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
L'istruzione HEALTHCHECK
dice a Docker come testare un contenitore per verificare che funzioni ancora. Questo può rilevare casi come un server Web bloccato in un ciclo infinito e incapace di gestire nuove connessioni, anche se il processo del server è ancora in esecuzione.
Quando un container ha un healthcheck specificato, ha uno stato di salute oltre al suo stato normale. Questo stato inizia inizialmente. Ogni volta che passa un controllo sanitario, diventa sano (qualunque stato fosse precedentemente). Dopo un certo numero di fallimenti consecutivi, diventa malsano.
Le opzioni che possono apparire prima di CMD
sono:
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)
Il controllo dello stato verrà eseguito per primi secondi dopo che il contenitore è stato avviato, e quindi di nuovo i secondi dopo il completamento di ogni controllo precedente.
Se una singola esecuzione del controllo richiede più tempo di un timeout, il controllo viene considerato non riuscito.
È necessario riprovare i fallimenti consecutivi del controllo dello stato perché il contenitore sia considerato non sano.
Ci può essere solo un'istruzione HEALTHCHECK
in un Dockerfile
. Se ne elenchiamo più di uno, solo l'ultimo HEALTHCHECK
avrà effetto.
Il comando dopo la parola chiave CMD
può essere un comando di shell (ad es. HEALTHCHECK CMD /bin/check-running
) o un array exec (come con altri comandi Dockerfile, vedere ad esempio ENTRYPOINT
per i dettagli).
Lo stato di uscita del comando indica lo stato di salute del contenitore. I valori possibili sono:
-
0: success
: il contenitore è integro e pronto all'uso -
1: unhealthy
: il contenitore non funziona correttamente -
2: starting
- il contenitore non è ancora pronto per l'uso, ma funziona correttamente
Se il probe restituisce 2 ("starting") quando il contenitore si è già spostato dallo stato "starting", viene invece considerato "malsano".
Ad esempio, per verificare ogni cinque minuti circa che un server Web sia in grado di servire la pagina principale del sito entro tre secondi:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
Per aiutare a eseguire il debug dei probe in errore, qualsiasi testo di output (codificato UTF-8) che il comando scrive su stdout o stderr verrà archiviato nello stato di docker inspect
e può essere interrogato con il docker inspect
. Tale output deve essere mantenuto breve (solo i primi 4096 byte sono attualmente memorizzati).
Quando cambia lo stato di salute di un contenitore, viene generato un evento health_status
con il nuovo stato.
La funzione HEALTHCHECK
è stata aggiunta a Docker 1.12.
SHELL Istruzione
SHELL ["executable", "parameters"]
L'istruzione SHELL
consente di sovrascrivere la shell di default utilizzata per la forma shell dei comandi. La shell predefinita su Linux è ["/bin/sh", "-c"]
, e su Windows è ["cmd", "/S", "/C"]
. L'istruzione SHELL
deve essere scritta in formato JSON in un Dockerfile.
L'istruzione SHELL
è particolarmente utile su Windows in cui esistono due shell native comunemente usate e abbastanza diverse: cmd e powershell, oltre a shell alternative disponibili tra cui sh.
L'istruzione SHELL
può apparire più volte. Ogni istruzione SHELL
sostituisce tutte le precedenti istruzioni SHELL
e influisce su tutte le istruzioni successive. Per esempio:
FROM windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
Le seguenti istruzioni possono essere influenzate dall'istruzione SHELL
quando la forma della shell di esse viene utilizzata in un Dockerfile: RUN
, CMD
e ENTRYPOINT
.
L'esempio seguente è un modello comune trovato su Windows che può essere ottimizzato usando l'istruzione SHELL
:
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
Il comando invocato dalla finestra mobile sarà:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
Questo è inefficiente per due ragioni. Innanzitutto, viene invocato un comando del comando cmd.exe non necessario (noto anche come shell). In secondo luogo, ogni istruzione RUN
nel modulo shell richiede un comando PowerShell supplementare che precede il comando.
Per rendere questo più efficiente, è possibile utilizzare uno dei due meccanismi. Uno è quello di utilizzare il modulo JSON del comando RUN
come:
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
Mentre il modulo JSON non è ambiguo e non usa il cmd.exe non necessario, richiede più verbosità attraverso la doppia citazione e l'escaping. Il meccanismo alternativo consiste nell'utilizzare l'istruzione SHELL
e la forma della shell, creando una sintassi più naturale per gli utenti di Windows, specialmente se combinata con la direttiva escape parser:
# escape=`
FROM windowsservercore
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
Con il risultato di:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM windowsservercore
---> 5bc36a335344
Step 2 : SHELL powershell -command
---> Running in 87d7a64c9751
---> 4327358436c1
Removing intermediate container 87d7a64c9751
Step 3 : RUN New-Item -ItemType Directory C:\Example
---> Running in 3e6ba16b8df9
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/2/2016 2:59 PM Example
---> 1f1dfdcec085
Removing intermediate container 3e6ba16b8df9
Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
---> 6770b4c17f29
Removing intermediate container b139e34291dc
Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
---> Running in abdcf50dfd1f
Hello from Execute-MyCmdlet.ps1 - passed hello world
---> ba0e25255fda
Removing intermediate container abdcf50dfd1f
Successfully built ba0e25255fda
PS E:\docker\build\shell>
L'istruzione SHELL
potrebbe anche essere utilizzata per modificare il modo in cui una shell funziona. Ad esempio, utilizzando SHELL cmd /S /C /V:ON|OFF
su Windows, è possibile modificare la semantica di espansione delle variabili di ambiente ritardate.
L'istruzione SHELL
può anche essere utilizzata su Linux se è richiesta una shell alternativa come zsh, csh, tcsh e altri.
La funzione SHELL
è stata aggiunta a Docker 1.12.
Installazione dei pacchetti Debian / Ubuntu
Eseguire l'installazione su un comando a esecuzione singola per unire l'aggiornamento e l'installazione. Se aggiungi altri pacchetti in un secondo momento, questo eseguirà di nuovo l'aggiornamento e installerà tutti i pacchetti necessari. Se l'aggiornamento viene eseguito separatamente, verrà memorizzato nella cache e le installazioni del pacchetto potrebbero non riuscire. Impostare il frontend su non interattivo e passare il -y per installare è necessario per le installazioni con script. La pulizia e lo spurgo alla fine dell'installazione riducono al minimo le dimensioni del livello.
FROM debian
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
openssh-client \
sudo \
vim \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*