В чем разница между CMD и ENTRYPOINT в Dockerfile?

В Dockerfiles есть две команды, которые похожи на меня: CMD а также ENTRYPOINT, Но я думаю, что между ними есть (тонкая?) Разница - иначе не было бы никакого смысла иметь две команды для одной и той же вещи.

Документация гласит для CMD

Основная цель CMD - предоставить значения по умолчанию для исполняемого контейнера.

и для ENTRYPOINT:

ENTRYPOINT помогает вам настроить контейнер, который вы можете запускать как исполняемый файл.

Итак, в чем разница между этими двумя командами?

21 ответ

Решение

Docker имеет точку входа по умолчанию, которая /bin/sh -c но не имеет команды по умолчанию.

Когда вы запускаете Docker, как это:docker run -i -t ubuntu bashточка входа по умолчанию /bin/sh -cизображение ubuntu и команда bash,

Команда запускается через точку входа. то есть фактическая вещь, которая исполняется /bin/sh -c bash, Это позволило Docker реализовать RUN быстро, полагаясь на парсер оболочки.

Позже, люди попросили, чтобы иметь возможность настроить это, так ENTRYPOINT а также --entrypoint были введены.

Все после ubuntu в приведенном выше примере это команда и передается в точку входа. При использовании CMD инструкция, это так же, как если бы вы делали docker run -i -t ubuntu <cmd>, <cmd> будет параметром точки входа.

Вы также получите тот же результат, если вместо этого наберете эту команду docker run -i -t ubuntu, Вы по-прежнему будете запускать оболочку bash в контейнере, поскольку в файле Docker для Ubuntu указан CMD по умолчанию: CMD ["bash"]

Поскольку все передается в точку входа, вы можете очень хорошо вести себя со своими изображениями. @Jiri пример хорош, он показывает, как использовать изображение в качестве "двоичного". Когда используешь ["/bin/cat"] в качестве точки входа, а затем делать docker run img /etc/passwd, ты понял, /etc/passwd является командой и передается точке входа, поэтому выполнение конечного результата просто /bin/cat /etc/passwd,

Другим примером может быть любой cli в качестве точки входа. Например, если у вас есть изображение Redis, вместо запуска docker run redisimg redis -H something -u toto get key, вы можете просто иметь ENTRYPOINT ["redis", "-H", "something", "-u", "toto"] и затем запустите так для того же результата: docker run redisimg get key,

ENTRYPOINT указывает команду, которая всегда будет выполняться при запуске контейнера.

CMD указывает аргументы, которые будут переданы ENTRYPOINT,

Если вы хотите сделать изображение, посвященное определенной команде, вы будете использовать ENTRYPOINT ["/path/dedicated_command"]

В противном случае, если вы хотите сделать изображение общего назначения, вы можете оставить ENTRYPOINT не указано и использовать CMD ["/path/dedicated_command"] так как вы сможете переопределить настройку, предоставив аргументы docker run,

Например, если ваш Dockerfile:

FROM debian:wheezy
ENTRYPOINT ["/bin/ping"]
CMD ["localhost"]

Запуск изображения без каких-либо аргументов пингует локальный хост:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms

Теперь, запуск изображения с аргументом будет проверять аргумент:

$ docker run -it test google.com
PING google.com (173.194.45.70): 48 data bytes
56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
^C--- google.com ping statistics ---
5 packets transmitted, 3 packets received, 40% packet loss
round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms

Для сравнения, если ваш Dockerfile:

FROM debian:wheezy
CMD ["/bin/ping", "localhost"]

Запуск изображения без каких-либо аргументов пингует локальный хост:

$ docker run -it test
PING localhost (127.0.0.1): 48 data bytes
56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
^C--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms

Но запуск изображения с аргументом запустит аргумент:

docker run -it test bash
root@e8bb7249b843:/#

Смотрите эту статью от Brian DeHamer для более подробной информации: https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/

Согласно докерской документации,

Инструкции CMD и ENTRYPOINT определяют, какая команда выполняется при запуске контейнера. Есть несколько правил, которые описывают их сотрудничество.

  1. В Dockerfile должен быть указан хотя бы один из CMD или же ENTRYPOINT команды.
  2. ENTRYPOINT должен быть определен при использовании контейнера в качестве исполняемого файла.
  3. CMD должен использоваться как способ определения аргументов по умолчанию для ENTRYPOINT команда или для выполнения специальной команды в контейнере.
  4. CMD будет переопределено при запуске контейнера с альтернативными аргументами.

В таблицах ниже показано, какая команда выполняется для разных ENTRYPOINT / CMD комбинации:

- No ENTRYPOINT

╔════════════════════════════╦═════════════════════════════╗
║ No CMD                     ║ error, not allowed          ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════╝

- ENTRYPOINT exec_entry p1_entry

╔════════════════════════════╦═══════════════════════════════════════════════════════════╗
║ No CMD                     ║ /bin/sh -c exec_entry p1_entry                            ║
╟────────────────────────────╫───────────────────────────────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ /bin/sh -c exec_entry p1_entry exec_cmd p1_cmd            ║
╟────────────────────────────╫───────────────────────────────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ /bin/sh -c exec_entry p1_entry p1_cmd p2_cmd              ║
╟────────────────────────────╫───────────────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ /bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd ║
╚════════════════════════════╩═══════════════════════════════════════════════════════════╝

- ENTRYPOINT [“exec_entry”, “p1_entry”]

╔════════════════════════════╦═════════════════════════════════════════════════╗
║ No CMD                     ║ exec_entry p1_entry                             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD [“exec_cmd”, “p1_cmd”] ║ exec_entry p1_entry exec_cmd p1_cmd             ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD [“p1_cmd”, “p2_cmd”]   ║ exec_entry p1_entry p1_cmd p2_cmd               ║
╟────────────────────────────╫─────────────────────────────────────────────────╢
║ CMD exec_cmd p1_cmd        ║ exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd  ║
╚════════════════════════════╩═════════════════════════════════════════════════╝

Да, это хороший вопрос. Я еще не совсем понимаю, но:

Я это понимаю ENTRYPOINT исполняемый файл Вы можете переопределить точку входа, указав --entrypoint = "".

docker run -t -i --entrypoint="/bin/bash" ubuntu

CMD является аргументом по умолчанию для контейнера. Без точки входа аргумент по умолчанию - это команда, которая выполняется. С точкой входа cmd передается точке входа в качестве аргумента. Вы можете эмулировать команду с точкой входа.

# no entrypoint
docker run ubuntu /bin/cat /etc/passwd

# with entry point, emulating cat command
docker run --entrypoint="/bin/cat" ubuntu /etc/passwd

Итак, главное преимущество в том, что с точкой входа вы можете передавать аргументы (cmd) в ваш контейнер. Для этого вам нужно использовать оба:

# Dockerfile
FROM ubuntu
ENTRYPOINT ["/bin/cat"]

а также

docker build -t=cat .

тогда вы можете использовать:

docker run cat /etc/passwd
#              ^^^^^^^^^^^
#                   CMD
#          ^^^      
#          image (tag)- using the default ENTRYPOINT

В двух словах:

  • CMD устанавливает команду и / или параметры по умолчанию, которые могут быть перезаписаны из командной строки при запуске контейнера Docker.
  • Команда и параметры ENTRYPOINT не будут перезаписаны из командной строки. Вместо этого все аргументы командной строки будут добавлены после параметров ENTRYPOINT.

Если вам нужно больше деталей или вы хотите увидеть разницу на примере, есть запись в блоге, в которой подробно сравниваются CMD и ENTRYPOINT с множеством примеров - http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

Разница между CMD и ENTRYPOINT по интуиции:

  • ENTRYPOINT: команда для запуска при запуске контейнера.
  • CMD: команда для запуска при запуске контейнера или аргументы для ENTRYPOINT, если указано.

Да, это смешивается.

Вы можете переопределить любой из них при запуске Docker Run.

Разница между CMD и ENTRYPOINT по примеру:

docker run -it --rm yourcontainer /bin/bash            <-- /bin/bash overrides CMD
                                                       <-- /bin/bash does not override ENTRYPOINT
docker run -it --rm --entrypoint ls yourcontainer      <-- overrides ENTRYPOINT with ls
docker run -it --rm --entrypoint ls yourcontainer  -la  <-- overrides ENTRYPOINT with ls and overrides CMD with -la

Подробнее о разнице между CMD а также ENTRYPOINT:

Аргумент к docker run такой как /bin/bash переопределяет любую команду CMD, которую мы написали в Dockerfile.

ENTRYPOINT нельзя переопределить во время выполнения с помощью обычных команд, таких как docker run [args], args в конце docker run [args] предоставляются в качестве аргументов для ENTRYPOINT. Таким образом, мы можем создать container который похож на нормальный двоичный файл, такой как ls,

Таким образом, CMD может выступать в качестве параметров по умолчанию для ENTRYPOINT, а затем мы можем переопределить аргументы CMD из [args].

ENTRYPOINT можно переопределить с помощью --entrypoint,

Я добавлю свой ответ в качестве примера1, который может помочь вам лучше понять разницу.

Предположим, мы хотим создать изображение, которое всегда будет запускать команду сна при запуске. Создадим собственное изображение и укажем новую команду:

FROM ubuntu
CMD sleep 10

Создание образа:

docker build -t custom_sleep .
docker run custom_sleep
# sleeps for 10 seconds and exits

Что, если мы хотим изменить количество секунд? Нам пришлось бы изменитьDockerfile поскольку значение там жестко запрограммировано, или переопределите команду, указав другую:

docker run custom_sleep sleep 20

Хотя это работает, это не очень хорошее решение, поскольку у нас есть избыточная команда "сна". Почему лишний? Поскольку единственная цель контейнера - спать, поэтому необходимо указатьsleep явно немного неудобно.

Теперь попробуем использовать ENTRYPOINT инструкция:

FROM ubuntu
ENTRYPOINT sleep

Эта инструкция определяет программу, которая будет запускаться при запуске контейнера.

Теперь мы можем запустить:

docker run custom_sleep 20

А как насчет значения по умолчанию? Ну, вы правильно угадали:

FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]

В ENTRYPOINT - это программа, которая будет запущена, и значение, переданное в контейнер, будет добавлено к ней.

В ENTRYPOINT можно переопределить, указав --entrypoint флаг, за которым следует новая точка входа, которую вы хотите использовать.

Не мой, я как-то смотрел туториал, в котором был этот пример

На это есть несколько хороших ответов. Я хочу объяснить это с помощью демонстрации для каждого документа

  • CMD определяет команды и / или параметры по умолчанию для контейнера. CMD - это инструкция, которую лучше всего использовать, если вам нужна команда по умолчанию, которую пользователи могут легко переопределить. Если Dockerfile имеет несколько CMD, он применяет только инструкции из последнего.
  • ENTRYPOINT предпочтительнее, если вы хотите определить контейнер с конкретным исполняемым файлом.

Вы не можете отменить ENTRYPOINT при запуске контейнера, если вы не добавите  --entrypoint флаг.

  1. CMD

Файл Docker

  FROM centos:8.1.1911

  CMD ["echo", "Hello Docker"]

Результат выполнения

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> hostname   # hostname is exec to override CMD
244be5006f32
  1. ТОЧКА ВХОДА

Файл Docker

  FROM centos:8.1.1911

  ENTRYPOINT ["echo", "Hello Docker"]

Результат выполнения

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> hostname   # hostname as parameter to exec
Hello Docker hostname
  1. Есть много ситуаций, в которых объединение CMD и ENTRYPOINT было бы лучшим решением для вашего контейнера Docker. В таких случаях  исполняемый файл определяется с помощью ENTRYPOINT, а CMD определяет параметр по умолчанию.

Файл Docker

  FROM centos:8.1.1911

  ENTRYPOINT ["echo", "Hello"]
  CMD ["Docker"]

Результат выполнения

$ sudo docker run <image-id>
Hello Docker
$ sudo docker run <image-id> Ben
Hello Ben

Принятый ответ невероятен в объяснении истории. Я нахожу, что эта таблица очень хорошо объясняет это из официального документа о том, "как взаимодействуют CMD и ENTRYPOINT":

Я наткнулся на это, и вначале я обнаружил, что это действительно сбивает с толку, если честно, и я думаю, что эта путаница возникает из-за использования слова "CMD", потому что на самом деле то, что там происходит, действует как аргумент. Итак, покопавшись, я понял, как это работает. В принципе:

ENTRYPOINT -> то, что вы укажете здесь, будет командой, которая будет выполняться при запуске контейнера. Если вы опустите это определение, докер будет использовать /bin/sh -c bash для запуска вашего контейнера.

CMD -> это аргументы, добавленные к ENTRYPOINT, если пользователь не указывает какой-либо настраиваемый аргумент, то есть: docker run ubuntu <custom_cmd> в этом случае вместо добавления того, что указано на изображении в разделе CMD, docker будет работать ENTRYPOINT <custom_cmd>. Если ENTRYPOINT не был указан, то, что здесь идет, будет передано в /bin/sh -c фактически действуя как команда, выполняемая при запуске контейнера.

Как бы то ни было, лучше объяснить происходящее на примерах. Допустим, я создаю простой образ докера, используя следующую спецификацию Dockerfile:

       From ubuntu
ENTRYPOINT ["sleep"]

Затем я создаю его, выполнив следующее:

       docker build . -t testimg

Это создаст контейнер, который каждый раз, когда вы запускаете, спит. Итак, если я запустил его следующим образом:

       docker run testimg

Я получу следующее:

       sleep: missing operand
Try 'sleep --help' for more information.

Это происходит потому, что точкой входа является команда "сна", которой нужен аргумент. Чтобы исправить это, я просто предоставлю количество сна:

       docker run testimg 5

Это будет работать правильно, и, как следствие, контейнер будет работать, засыпает 5 секунд и выходит. Как мы видим в этом примере, докер просто добавил то, что идет после имени изображения, в двоичный файл точки входа. docker run testimg <my_cmd>. Что произойдет, если мы захотим передать в точку входа значение по умолчанию (аргумент по умолчанию)? в этом случае нам просто нужно указать его в разделе CMD, например:

       From ubuntu
ENTRYPOINT ["sleep"]
CMD ["10"]

В этом случае, если пользователь не передаст аргумент, контейнер будет использовать значение по умолчанию (10) и передать его в спящий режим точки входа.

Теперь давайте использовать только CMD и опустить определение ENTRYPOINT:

       FROM ubuntu
CMD ["sleep", "5"]

Если мы перестроим и запустим этот образ, он будет спать в течение 5 секунд.

Таким образом, вы можете использовать ENTRYPOINT, чтобы ваш контейнер работал как исполняемый файл. Вы можете использовать CMD для предоставления аргументов по умолчанию вашей точке входа или для запуска настраиваемой команды при запуске вашего контейнера, которая может быть переопределена извне пользователем.

Я хотел бы легко различать различия между CMD, RUN и ENTRYPOINT .

Давайте возьмем пример инициализации npm для node.

Командная строка:

Предположим, что ниже приведена начальная команда, которую мы добавили в файл dockerfile.

      CMD [ "npm", "init" ]

Теперь, если я побегуdocker run -t node npm install

Это переопределит команду инициализации npm из файла dockerfile.

      CMD [ "npm", "init" ] This will become  CMD [ "npm", "install" ]

Он будет выполнятьnpm installкомандовать, а неnpm initпоскольку он переопределяет установку npm.

Теперь поговорим о

ВХОДНАЯ ТОЧКА :

Предположим, что эта же команда добавлена ​​в файл докера, но с ENTRYPOINT

      ENTRYPOINT [ "npm", "init" ]

Теперь, если я побегуdocker run -t node install

Он добавит команду npm init с npm install в dockerfile.

      ENTRYPOINT [ "npm", "init" ] This will become  ENTRYPOINT [ "npm", "init", "install" ]

Он выполнит команды npm init и npm install.

Подводить итоги :

RUN: это будет выполняться во время создания образа. Используется для установки любых зависимостей, таких как node_modules. Бывший.RUN npm install

CMD: использовать, когда вы хотите переопределить всю команду

ENTRYPOINT: Используется, когда вы хотите добавить какую-то дополнительную команду.

Я прочитал все ответы и хочу подвести итог для лучшего понимания на первый взгляд, например:

Во-первых, вся команда, выполняемая в контейнере, состоит из двух частей: команды и аргументов.

  • ENTRYPOINT определяет исполняемый файл, вызываемый при запуске контейнера (для команды)

  • CMD указывает аргументы, которые передаются в ENTRYPOINT (для аргументов)

В книге Kubernetes In Action есть важное замечание по этому поводу. (глава 7)

Хотя вы можете использовать инструкцию CMD, чтобы указать команду, которую вы хотите выполнить при запуске образа, правильный способ - сделать это с помощью инструкции ENTRYPOINT и указать CMD только в том случае, если вы хотите определить аргументы по умолчанию.

Вы также можете прочитать эту статью, чтобы получить подробное объяснение простым способом

Комментарии к функции EntryPoint в коде

// ENTRYPOINT /usr/sbin/nginx.

// Установить точку входа (по умолчанию sh -c) в /usr/sbin/nginx.

// Примем CMD в качестве аргументов /usr/sbin/nginx.

Еще одна ссылка из документов

Вы можете использовать форму exec ENTRYPOINT, чтобы установить довольно стабильные команды и аргументы по умолчанию, а затем использовать CMD, чтобы установить дополнительные значения по умолчанию, которые с большей вероятностью будут изменены.

Пример:

FROM ubuntu:14.04.3
ENTRYPOINT ["/bin/ping"]
CMD ["localhost", "-c", "2"]

Сборка: сборка sudo docker -t ent_cmd.

CMD arguments are easy to override.

NO argument (sudo docker -it ent_cmd)                :  ping localhost 
argument    (sudo docker run -it ent_cmd google.com) :  ping google.com

,

To override EntryPoint argument, you need to supply entrypoint
sudo docker run -it --entrypoint="/bin/bash" ent_cmdd

ps: при наличии EntryPoint CMD будет содержать аргументы для подачи в EntryPoint. В отсутствие EntryPoint CMD будет командой, которая будет выполняться.

CMD:

  • CMD ["executable","param1","param2"]: ["executable","param1","param2"] это первый процесс.
  • CMD command param1 param2: /bin/sh -c CMD command param1 param2 это первый процесс. CMD command param1 param2 разветвляется с первого процесса.
  • CMD ["param1","param2"]: Эта форма используется для предоставления аргументов по умолчанию для ENTRYPOINT,

ENTRYPOINT (В следующем списке не рассматривается случай, когда CMD и ENTRYPOINT используются вместе):

  • ENTRYPOINT ["executable", "param1", "param2"]: ["executable", "param1", "param2"] это первый процесс.
  • ENTRYPOINT command param1 param2: /bin/sh -c command param1 param2 это первый процесс. command param1 param2 разветвляется с первого процесса.

Как сказал creack, CMD был разработан первым. Затем была разработана ENTRYPOINT для дополнительной настройки. Так как они не спроектированы вместе, между CMD и ENTRYPOINT существуют некоторые функциональные совпадения, которые часто путают людей.

CMD команда упоминается внутри Dockerfile файл может быть переопределен через docker run команда пока ENTRYPOINT не может быть.

• В Dockerfile должна быть указана хотя бы одна инструкция CMD или ENTRYPOINT.

• Будут использоваться только последние CMD и ENTRYPOINT в Dockerfile.

• ENTRYPOINT следует определять при использовании контейнера в качестве исполняемого файла.

• Вы должны использовать инструкцию CMD как способ определения аргументов по умолчанию для команды, определенной как ENTRYPOINT, или для выполнения специальной команды в контейнере.

• CMD будет переопределен при запуске контейнера с альтернативными аргументами

• ENTRYPOINT устанавливает конкретное приложение по умолчанию, которое используется каждый раз, когда контейнер создается с использованием образа.

• Если вы соедините ENTRYPOINT с CMD, вы можете удалить исполняемый файл из CMD и просто оставить его аргументы, которые будут переданы в ENTRYPOINT

• Лучше всего использовать ENTRYPOINT для установки основной команды изображения, позволяя запускать этот образ, как если бы это была эта команда (а затем использовать CMD в качестве флагов по умолчанию)

Большинство людей прекрасно объясняют это здесь, поэтому я не буду повторять все ответы. Но чтобы получить хорошее чувство, я бы предложил проверить его самостоятельно, посмотрев на процессы в контейнере.

Создайте крошечный Dockerfile формы:

FROM ubuntu:latest
CMD /bin/bash

Построй, запусти с docker run -it theimage и беги ps -eo ppid,pid,args в контейнере. Сравните этот вывод с выводом, который вы получаете от ps при использовании:

  • docker run -it theimage bash
  • Восстановление изображения, но с ENTRYPOINT /bin/bash и запустить его в обе стороны
  • С помощью CMD ["/bin/bash"]
  • ...

Таким образом, вы легко увидите различия между всеми возможными для себя методами.

Официальная документация лучших практик Dockerfile отлично объясняет различия.Лучшие практики Dockerfile

CMD:

Инструкция CMD должна использоваться для запуска программного обеспечения, содержащегося в вашем изображении, вместе с любыми аргументами. CMD почти всегда следует использовать в видеCMD ["executable", "param1", "param2"…]. Таким образом, если образ предназначен для службы, такой как Apache и Rails, вы должны запустить что-то вродеCMD ["apache2","-DFOREGROUND"]. Действительно, такая форма инструкции рекомендуется для любого служебного образа.

ТОЧКА ВХОДА:

Лучше всего использовать ENTRYPOINT для установки основной команды изображения, позволяя запускать это изображение, как если бы это была эта команда (а затем использовать CMD в качестве флагов по умолчанию).

В Dockerfile оба и используются для определения того, какую команду следует запускать при запуске контейнера. Однако у них разные цели и поведение:

  1. :
    • используется для предоставления аргументов по умолчанию для команды точки входа. Обычно он используется для указания основной команды, которая будет выполняться при запуске контейнера.
    • Вы можете переопределить, передав аргументы командной строки при запуске контейнера.
    • Если Dockerfile содержит несколько инструкций, вступит в силу только последняя.
    • ЕслиCMDкоманда отсутствует, образ Docker может не запуститься сам по себе.

Пример:

      FROM ubuntu
CMD ["echo", "Hello, World"]

В этом примере команда по умолчанию для контейнера установлена ​​на . При необходимости вы можете переопределить эту команду при запуске контейнера.

  1. :
    • используется для указания основной команды, которая будет выполняться при запуске контейнера, и не позволяет легко переопределить ее с помощью аргументов командной строки.
    • Любые дополнительные аргументы, передаваемые вdocker runкоманда будет добавлена ​​к команде, а не заменит ее.
    • ENTRYPOINTчасто используется для определения основного исполняемого файла контейнера, например конкретного приложения или службы.

Пример:

      FROM ubuntu
ENTRYPOINT ["echo", "Hello, World"]

В этом примере основная команда контейнера имеет значениеecho "Hello, World". Если вы запустите контейнер с дополнительными аргументами, например:

      docker run my-container "Goodbye, World"

Он выполнит:echo "Hello, World" "Goodbye, World".

Это, вероятно, лучшее описание, которое я нашел: Dockerfile: ENTRYPOINT vs CMD

У меня здесь было резюме, но люди продолжали голосовать без объяснения причин, поэтому я удалил его.

От пересборки образа ОС с нуля (просто написаниеFROM scratchи копирование минимальной файловой системы с COPY в dockerfile) я узнал, что

Если вы не укажете ENTRYPOINT и CMD в вашем файле докеров, докер будет использовать

      /bin/sh -c

в качестве ENTRYPOINT по умолчанию и примет CMD, если вы определите CMD в файле докера или передадите аргумент командной строки (который переопределит определенный CMD) во время запуска контейнера.

Предположим, вы передаете аргумент (или определяете CMD в dockerfile)lsзатем он будет передан в ENTRYPOINT. То есть,

      /bin/sh -c ls

собирается запустить любой переданный ему аргумент. Вы получите вывод для команды «ls», после чего контейнер закроется.


Образ ubuntu не определяет ENTRYPOINT явно, поэтому docker/bin/sh -cно содержит CMD, т.е. это означает, что когда вы запускаете следующую команду для запуска контейнера,

      docker container run -it ubuntu

Docker фактически использует ENTRYPOINT как /bin/sh -cа затем кормит его, и в конечном итоге то, что работает,

      /bin/sh -c bash

который запускает интерактивный терминал bash (только если-iфлаг указывается, как указано выше, и необязательно -t, чтобы получить собственный терминал, например опыт)

когда вы предоставляете аргументы через командную строку,bashзаменяется тем, что вы передаете, и вывод соответствует этому, т.е.

      /bin/sh -c passed_argument

Вы можете определить пользовательскую ENTRYPOINT, которая переопределит точку по умолчанию, но тогда вам нужно будет использовать CMD соответственно.

В случаеRUNкоманда в dockerfile, она не учитывает определенныеENTRYPOINTиCMDно запускает указанные команды, поскольку они предоставляются интерактивному терминалу bash в промежуточном контейнере

Другие вопросы по тегам