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

Ответ

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

CMD (Command)

Назначение:

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

Поведение при запуске:

  • Легко переопределяется при запуске контейнера, передав новую команду в docker run <image> <новая_команда>. Это позволяет пользователю запускать произвольные команды внутри контейнера.
  • Если ENTRYPOINT не указан, CMD определяет основную команду, которая будет выполнена.

Пример:

FROM alpine
CMD ["echo", "Hello from CMD"]
  • Запуск: docker run <image> выведет Hello from CMD.
  • Переопределение: docker run <image> echo "Overridden CMD" выведет Overridden CMD.

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

ENTRYPOINT (Entrypoint)

Назначение:

  • Определяет основную команду или исполняемый файл, который всегда будет запускаться при старте контейнера.
  • Превращает образ в исполняемый файл, делая его похожим на обычную программу.
  • Аргументы, переданные в docker run, или команда из CMD (если она есть), добавляются как аргументы к ENTRYPOINT.

Поведение при запуске:

  • Не переопределяется напрямую аргументами docker run. Аргументы docker run становятся параметрами для ENTRYPOINT.
  • Для переопределения ENTRYPOINT необходимо явно использовать флаг --entrypoint в docker run.

Пример:

FROM alpine
ENTRYPOINT ["echo"]
CMD ["Hello from ENTRYPOINT"]
  • Запуск: docker run <image> выведет Hello from ENTRYPOINT (CMD используется как аргумент для ENTRYPOINT).
  • Передача аргументов: docker run <image> "New argument" выведет New argument (CMD заменяется на "New argument").
  • Переопределение ENTRYPOINT: docker run --entrypoint "/bin/sh" <image> запустит /bin/sh внутри контейнера.

Почему используется: Для создания контейнера, который ведет себя как исполняемая программа (например, утилита командной строки или сервис), где ENTRYPOINT является этой программой, а CMD — ее аргументами по умолчанию.

Ключевое отличие:

  • CMD предоставляет аргументы по умолчанию для ENTRYPOINT или команду по умолчанию, которую легко переопределить.
  • ENTRYPOINT определяет основной исполняемый файл контейнера, который не меняется, а принимает CMD или аргументы docker run как свои параметры.