Існуючі відповіді охоплюють більшість того, що знадобиться кожному, хто дивиться на це питання. Тож я просто висвітлю деякі ділянки ніші для CMD та RUN.
CMD: Дублікати дозволено, але марно
GingerBeer робить важливий момент: ви не помилитесь, якщо введете більше одного CMD - але це марно робити. Я хотів би детальніше пояснити приклад:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
Якщо ви вбудуєте це у зображення та запустите контейнер із цим зображенням, то, як заявляє GingerBeer, слід прислухатися до останнього CMD. Отже, вихід цього контейнера буде:
Виконання CMD 2
Як я думаю про це, це те, що "CMD" встановлює єдину глобальну змінну для всього створюваного образу, тому послідовні "CMD" заяви просто перезаписують будь-які попередні записи до цієї глобальної змінної, а в кінцевому образі, на якому будується останній, хто пише перемоги. Оскільки Dockerfile виконує порядок зверху вниз, ми знаємо, що найменший CMD - це той, який отримує остаточне "записування" (метафорично кажучи).
RUN: Команди можуть не виконуватись, якщо зображення кешовані
Тонкий момент, який слід помітити про RUN, полягає в тому, що він трактується як чиста функція, навіть якщо є побічні ефекти, і таким чином кешується. Це означає, що якщо RUN мав деякі побічні ефекти, які не змінюють результуюче зображення, а це зображення вже кешоване, RUN не буде виконуватися знову, і тому побічні ефекти не відбудуться при наступних збірках. Наприклад, візьміть цей Dockerfile:
FROM busybox
RUN echo "Just echo while you work"
Перший раз, коли ви запустите його, ви отримаєте такий вихід, з різними буквено-цифровими ідентифікаторами:
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
Зауважте, що оператор echo був виконаний у зазначеному вище. Вдруге запустивши його, він використовує кеш, і ви не побачите відлуння у висновку збірки:
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