Різниця між RUN та CMD в Dockerfile


294

Я заплутався про те, коли я повинен використовувати CMDпроти RUN. Наприклад, для виконання bash / shell команд (тобто ls -la) я б завжди використовував CMDабо чи є ситуація, коли я б використовував RUN? Намагання зрозуміти кращі практики щодо цих двох подібних Dockerfileдиректив.


Відповіді:


426

RUN - етап складання зображення, стан контейнера після того, як RUNбуде виконана команда для образу контейнера. У Dockerfile може бути багато RUNкроків цього шару один над одним для створення зображення.

CMD - це команда, яку контейнер виконує за замовчуванням під час запуску вбудованого зображення. Докерфайл використовуватиме лише остаточне CMDвизначене. CMDМоже бути перевизначений при запуску контейнера з docker run $image $other_command.

ENTRYPOINT також тісно пов'язаний CMDі може змінювати спосіб, яким контейнер починає зображення.


15
ви робите все RUNнеобхідне для налаштування свого середовища, і ваш (тільки) CMD запускає процес, запущений у вашому контейнері, наприклад, для nginx, витяг з github.com/nginxinc/docker-nginx/blob/… ви бачите рядокCMD ["nginx", "-g", "daemon off;"]
user2915097

"Dockerfile може мати лише один CMD" - це не технічно правда, але фактично всі, крім одного, будуть ігноровані. Дивіться відповідь GingerBeer.
Colm Bhandal

"Dockerfile використовуватиме лише остаточний визначений CMD"? насправді, остаточний визначений CMD буде використаний для запуску зображення як контейнера, правда?
paul cheung

1
Так @paulcheung, остання команда в dockerfile записується до зображення і є командою, яку контейнер виконує за замовчуванням під час запуску вбудованого зображення.
Метт

126

RUN - команда запускає, коли ми будуємо зображення докера.

CMD - команда запускає, коли ми запускаємо створене зображення докера.


67

Я знайшов цю статтю дуже корисно , щоб зрозуміти різницю між ними:

RUN - інструкція RUN дозволяє встановити свою програму та необхідні для неї пакети. Він виконує будь-які команди поверх поточного зображення і створює новий шар, здійснюючи результати. Часто ви знайдете кілька інструкцій RUN в Dockerfile.

CMD - інструкція CMD дозволяє встановити команду за замовчуванням, яка буде виконуватися лише при запуску контейнера без вказівки команди. Якщо контейнер Docker працює з командою, команда за замовчуванням буде проігнорована. Якщо в Dockerfile є більше однієї інструкції CMD, всі, крім останніх
інструкцій CMD, ігноруються.


13

RUN - Встановіть Python, ваш контейнер тепер записав python у своє зображення
CMD - python hello.py, запустіть улюблений сценарій


CMD - Встановити Python, тепер мій контейнер не значить, щоб Python записався у його зображення?
Карлос Фонтес

RUN створить шар зображення python, CMD просто виконає команду не створювати зображення
Rohit Salecha

8

Команда RUN: Команда RUN в основному виконує команду за замовчуванням, коли ми будуємо зображення. Він також здійснить зміни зображення для наступного кроку.

Для створення нового зображення може бути більше 1 команди RUN.

Команда CMD: Команди CMD просто встановлять команду за замовчуванням для нового контейнера. Це не буде виконано під час збирання.

Якщо файл докера містить більше 1 команд CMD, всі вони ігноруються, крім останньої. Оскільки ця команда нічого не виконає, а лише встановить команду за замовчуванням.


6

Примітка. Не плутайте RUN з CMD. RUN насправді виконує команду і здійснює результат; CMD не виконує нічого під час збирання, але вказує передбачувану команду для зображення.

з посилання на файл докер

https://docs.docker.com/engine/reference/builder/#cmd


4

RUN : їх може бути багато, і він використовується в процесі збирання , наприклад, встановити кілька бібліотек

CMD : Може тільки 1, що ваш виконати початкову точку (наприклад ["npm", "start"], ["node", "app.js"])


2

Відповідей щодо RUN та CMD було достатньо . Я просто хочу додати кілька слів про ENTRYPOINT . Аргументи CMD можна перезаписати аргументами командного рядка, тоді як аргументи ENTRYPOINT завжди використовуються.

Ця стаття є хорошим джерелом інформації.


2

Існуючі відповіді охоплюють більшість того, що знадобиться кожному, хто дивиться на це питання. Тож я просто висвітлю деякі ділянки ніші для 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.