Gymterview
middle

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

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

CMD — команда по умолчанию

CMD задаёт команду, которая легко переопределяется аргументами docker run:

Пример
FROM eclipse-temurin:17-jre-alpine
CMD ["java", "-jar", "app.jar"]
Пример
# Выполнит java -jar app.jar
docker run myapp

# CMD полностью заменяется: выполнит /bin/sh
docker run myapp /bin/sh

ENTRYPOINT — основная команда

ENTRYPOINT задаёт основную команду, а аргументы docker run добавляются к ней:

Пример
FROM eclipse-temurin:17-jre-alpine
ENTRYPOINT ["java", "-jar", "app.jar"]
Пример
# Выполнит java -jar app.jar
docker run myapp

# Аргументы добавятся: java -jar app.jar --spring.profiles.active=prod
docker run myapp --spring.profiles.active=prod

Комбинация ENTRYPOINT + CMD

Идиоматический подход: ENTRYPOINT задаёт исполняемый файл, а CMD — аргументы по умолчанию:

Пример
FROM eclipse-temurin:17-jre-alpine
ENTRYPOINT ["java", "-jar", "app.jar"]
CMD ["--spring.profiles.active=dev"]
Пример
# Выполнит java -jar app.jar --spring.profiles.active=dev
docker run myapp

# CMD заменяется: java -jar app.jar --spring.profiles.active=prod
docker run myapp --spring.profiles.active=prod

Формы записи

Форма Синтаксис PID 1 Сигналы ОС
Exec-форма (рекомендуется) ENTRYPOINT ["java", "-jar", "app.jar"] Процесс Java Доходят напрямую
Shell-форма ENTRYPOINT java -jar app.jar /bin/sh -c Не доходят до Java

Shell-форма оборачивает команду в /bin/sh -c, из-за чего Java-процесс не получает PID 1 и сигналы ОС (SIGTERM) не доходят до приложения напрямую. Это приводит к проблемам с graceful shutdown.

На собеседовании: ключевое различие: CMD легко переопределяется целиком, а к ENTRYPOINT аргументы добавляются. Идиоматический подход — комбинация ENTRYPOINT + CMD. Обязательно упомяните exec-форму и проблему PID 1 при shell-форме — это показывает production-опыт.