Istniejące odpowiedzi obejmują większość tego, czego potrzebowałby każdy, kto spojrzy na to pytanie. Więc po prostu zajmę się niektórymi niszowymi obszarami dla CMD i RUN.
CMD: Duplikaty są dozwolone, ale marnotrawne
GingerBeer robi ważny punkt: nie popełnisz żadnych błędów, jeśli włożysz więcej niż jeden CMD - ale marnowanie tego. Chciałbym rozwinąć przykład:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
Jeśli wbudujesz to w obraz i uruchomisz kontener na tym obrazie, to jak stwierdza GingerBeer, tylko ostatnia CMD zostanie uwzględniona. Wyjście tego kontenera będzie:
Wykonywanie CMD 2
Myślę, że „CMD” ustawia pojedynczą zmienną globalną dla całego budowanego obrazu, więc kolejne instrukcje „CMD” po prostu nadpisują wszelkie wcześniejsze zapisy do tej zmiennej globalnej, a na ostatecznym obrazie, który jest zbudowany ostatni do pisania wygrywa. Ponieważ plik Docker jest wykonywany w kolejności od góry do dołu, wiemy, że najniższy CMD to ten, który otrzymuje ten końcowy „zapis” (mówiąc metaforycznie).
RUN: polecenia mogą nie zostać wykonane, jeśli obrazy są buforowane
Subtelną kwestią, na którą należy zwrócić uwagę na RUN, jest to, że jest on traktowany jako czysta funkcja, nawet jeśli występują skutki uboczne, i dlatego jest buforowany. Oznacza to, że jeśli RUN miał jakieś skutki uboczne, które nie zmieniają obrazu wynikowego, a ten obraz został już zbuforowany, RUN nie zostanie wykonany ponownie, więc efekty uboczne nie wystąpią przy kolejnych kompilacjach. Na przykład weź ten plik Docker:
FROM busybox
RUN echo "Just echo while you work"
Przy pierwszym uruchomieniu otrzymasz dane wyjściowe takie jak ten, z różnymi identyfikatorami alfanumerycznymi:
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
Zauważ, że instrukcja echa została wykonana powyżej. Przy drugim uruchomieniu używa pamięci podręcznej i nie zobaczysz echa w wynikach kompilacji:
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