В каком порядке выполняются инструкции CMD и ENTRYPOINT в Dockerfile, если указаны обе?

Ответ

При совместном использовании ENTRYPOINT и CMD в Dockerfile они объединяются для формирования полной команды запуска контейнера.

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

Пример Dockerfile:

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

Результат запуска контейнера без своих аргументов:

Hello World

Если передать свои аргументы при запуске (docker run <image> <args>):

docker run my-image Universe
# Результат: Hello Universe

В этом случае CMD ["World"] будет полностью заменён переданными аргументами (Universe).

Важные детали:

  • Формат имеет значение. Если ENTRYPOINT указан в shell-формате (например, ENTRYPOINT echo Hello), то CMD будет проигнорирован, а команда запустится в отдельном shell-процессе.
  • Используйте exec-формат (с квадратными скобками) для ENTRYPOINT, чтобы CMD работал как задумано, и контейнер получал сигналы напрямую.

Ответ 18+ 🔞

А, ну это же классика, ебать мои старые костыли! Смотри, тут про ENTRYPOINT и CMD в докере. Ёпта, это как два пацана, которые всегда вместе бухают, но один главный, а второй подносит.

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

Вот смотри, как это работает, на примере: Допустим, у тебя в Dockerfile написано вот так:

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

Когда ты запускаешь контейнер просто так, без своих прибамбасов, он склеит это всё.

Hello World

Всё, приехали. Но если ты при запуске сам аргументы напишешь, то CMD нахуй отправляется, и подставляется твоё.

docker run my-image Universe
# А на выходе будет: Hello Universe

Видишь? ["World"] просто выкинули и заменили на твой Universe. Пизда рулю старому.

А теперь, чувак, самое важное, где все обжигаются — формат записи. Это пиздец важно.

  • Если ты ENTRYPOINT запишешь в shell-формате (типа ENTRYPOINT echo Hello), то это всё пойдёт через отдельную оболочку. И твой бедный CMD просто проигнорируют, на него всем будет похуй. Контейнер ещё и сигналы нормально получать не будет.
  • Поэтому всегда юзай exec-формат — эти квадратные скобочки ["echo", "Hello"]. Тогда CMD будет работать как надо, и контейнер будет получать сигналы напрямую, без посредников. Иначе потом будешь охуевать, почему ничего не работает.