Різниця між 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.