Встречается на 20% собеседований по DevOps

Что такое entrypoint \ cmd

ENTRYPOINT и CMD — это две инструкции в Dockerfile, которые определяют команду и параметры, исполняемые при запуске контейнера. Они похожи, но служат разным целям и взаимодействуют между собой: ENTRYPOINT задает исполняемый файл, а CMD — аргументы по умолчанию для него.

Как это работает

При запуске контейнера Docker объединяет ENTRYPOINT и CMD в одну команду. Если ENTRYPOINT не указан, CMD может использоваться для указания полной команды. Если ENTRYPOINT указан, CMD добавляет аргументы к нему. При запуске контейнера с помощью docker run можно переопределить CMD, передав аргументы после имени образа. ENTRYPOINT при этом остаётся неизменным, если только не использовать флаг --entrypoint.

Пример

Рассмотрим два подхода на примере Python-приложения.

Только ENTRYPOINT:

dockerfile
FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python", "app.py"]

Здесь при запуске контейнера всегда выполняется python app.py. Любые аргументы, переданные в docker run, будут добавлены к этой команде. Например, docker run myimage --help выполнит python app.py --help.

ENTRYPOINT и CMD вместе:

dockerfile
FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]

Здесь ENTRYPOINT задаёт команду python, а CMD — аргумент по умолчанию app.py. При запуске docker run myimage выполнится python app.py. Если передать аргументы, например docker run myimage hello.py, то CMD будет переопределён, и выполнится python hello.py.

Подводные камни

  • Переопределение CMD: CMD легко переопределяется аргументами командной строки, что удобно для гибкости, но может привести к неожиданному поведению, если не учитывать это.
  • Переопределение ENTRYPOINT: Чтобы изменить ENTRYPOINT, нужно использовать флаг --entrypoint в docker run, что менее очевидно.
  • Форма записи: Обе инструкции могут быть в exec-форме (JSON-массив) или shell-форме (строка). Exec-форма предпочтительнее, так как она не запускает оболочку и позволяет корректно передавать сигналы.
  • Отсутствие ENTRYPOINT: Если ENTRYPOINT не задан, CMD становится полной командой. В этом случае переопределить её можно просто передав аргументы.

Когда использовать

  • Используйте ENTRYPOINT, когда контейнер должен вести себя как исполняемый файл с фиксированной командой, а CMD — для аргументов по умолчанию, которые пользователь может легко переопределить.
  • Если нужна максимальная гибкость и контейнер может выполнять разные команды, лучше задать только CMD.
  • Для сервисов, которые всегда запускают один и тот же процесс (например, веб-сервер), комбинация ENTRYPOINT + CMD даёт удобный интерфейс: пользователь может передавать дополнительные флаги, не меняя основную команду.

Коротко

  • ENTRYPOINT — фиксированная команда, CMD — аргументы по умолчанию.
  • CMD переопределяется аргументами docker run, ENTRYPOINT — только флагом --entrypoint.
  • Используйте exec-форму (["команда", "аргумент"]) для избежания проблем с сигналами.
  • Если ENTRYPOINT нет, CMD задаёт всю команду.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы