Le risposte esistenti coprono la maggior parte di ciò di cui chiunque avrebbe bisogno a questa domanda. Quindi tratterò solo alcune aree di nicchia per CMD e RUN.
CMD: i duplicati sono consentiti ma dispendiosi
GingerBeer fa un punto importante: non otterrai errori se inserisci più di un CMD - ma è inutile farlo. Vorrei elaborare con un esempio:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
Se lo costruisci in un'immagine ed esegui un contenitore in questa immagine, come afferma GingerBeer, verrà ascoltato solo l'ultimo CMD. Quindi l'output di quel contenitore sarà:
Esecuzione di CMD 2
Il modo in cui ci penso è che "CMD" sta impostando una singola variabile globale per l'intera immagine che viene costruita, quindi le istruzioni "CMD" successive semplicemente sovrascrivono qualsiasi scrittura precedente a quella variabile globale e nell'immagine finale che ha creato il l'ultimo a scrivere vince. Poiché un Dockerfile viene eseguito in ordine dall'alto verso il basso, sappiamo che il CMD più in basso è quello che ottiene questa "scrittura" finale (metaforicamente parlando).
ESEGUI: i comandi non possono essere eseguiti se le immagini sono memorizzate nella cache
Un punto sottile da notare su RUN è che viene trattato come una funzione pura anche se ci sono effetti collaterali, e quindi viene memorizzato nella cache. Ciò significa che se RUN ha avuto alcuni effetti collaterali che non cambiano l'immagine risultante e quell'immagine è già stata memorizzata nella cache, il RUN non verrà eseguito di nuovo e quindi gli effetti collaterali non si verificheranno nelle build successive. Ad esempio, prendi questo Dockerfile:
FROM busybox
RUN echo "Just echo while you work"
La prima volta che lo esegui, otterrai un output come questo, con diversi ID alfanumerici:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
Si noti che l'istruzione echo è stata eseguita in quanto sopra. La seconda volta che lo esegui, utilizza la cache e non vedrai alcun eco nell'output della build:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Using cache
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest