← Назад к вопросам
Что произойдет если указать ENTRYPOINT и CMD в Dockerfile?
2.0 Middle🔥 171 комментариев
#Docker и контейнеризация
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI21 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# ENTRYPOINT и CMD в Dockerfile: когда они оба указаны
Краткий ответ
Если в Dockerfile указаны оба ENTRYPOINT и CMD, то CMD используется как аргументы (параметры) для ENTRYPOINT, а не как самостоятельная команда.
Детальное объяснение
Три формата команд в Docker
1. Shell form (shell форма):
ENTRYPOINT echo "Hello"
CMD ["World"]
2. Exec form (exec форма) — рекомендуется:
ENTRYPOINT ["echo", "Hello"]
CMD ["World"]
3. Комбинация форм:
ENTRYPOINT ["echo"] # exec form
CMD "World" # shell form
Правило взаимодействия
Когда оба указаны:
FROM alpine:latest
ENTRYPOINT ["echo", "Hello"]
CMD ["World"]
Выполнится:
echo Hello World
Команда будет: ENTRYPOINT + CMD = финальная команда
Практические примеры
Пример 1: Python приложение
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# ENTRYPOINT — главная команда
ENTRYPOINT ["python", "/app/app.py"]
# CMD — параметры по умолчанию
CMD ["--config", "/etc/app.conf"]
При docker run myimage:
python /app/app.py --config /etc/app.conf
При docker run myimage --debug:
python /app/app.py --debug
# CMD заменяется на --debug
Пример 2: Flask приложение
FROM python:3.9
WORKDIR /app
ENTRYPOINT ["flask"]
CMD ["run", "--host=0.0.0.0"]
По умолчанию:
flask run --host=0.0.0.0
При docker run myimage db upgrade:
flask db upgrade
# CMD полностью заменяется
Пример 3: Node.js сервис
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm ci
ENTRYPOINT ["node"]
CMD ["src/server.js"]
Запуск контейнера:
# Вариант 1: используется CMD
$ docker run myapp
# Выполняется: node src/server.js
# Вариант 2: переопределяем CMD
$ docker run myapp src/cli.js
# Выполняется: node src/cli.js
# Вариант 3: переопределяем и ENTRYPOINT, и CMD
$ docker run --entrypoint npm myapp start
# Выполняется: npm start
Важные различия
Когда указан только CMD
FROM ubuntu:20.04
CMD ["echo", "Hello"]
$ docker run myimage
# Выполняется: echo Hello
$ docker run myimage ls -la
# Выполняется: ls -la (CMD заменен полностью)
Когда указан только ENTRYPOINT
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
$ docker run myimage
# Выполняется: echo (пусто)
$ docker run myimage Hello
# Выполняется: echo Hello (аргумент добавлен)
$ docker run --entrypoint ls myimage -la
# Выполняется: ls -la (ENTRYPOINT переопределён)
Когда указаны оба
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD ["Hello"]
$ docker run myimage
# Выполняется: echo Hello
$ docker run myimage World
# Выполняется: echo World (CMD заменен)
$ docker run --entrypoint ls myimage -la
# Выполняется: ls -la (ENTRYPOINT переопределён, CMD игнорируется)
Shell form vs Exec form
Shell form — ОПАСНО для ENTRYPOINT
FROM ubuntu:20.04
ENTRYPOINT echo Hello
CMD World
Проблема: CMD не будет передан как аргумент!
$ docker run myimage
# Выполняется: /bin/sh -c "echo Hello"
# World не используется!
Exec form — ПРАВИЛЬНО
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD ["World"]
$ docker run myimage
# Выполняется: echo World (корректно)
Таблица поведения
| Dockerfile | docker run | Результат |
|---|---|---|
CMD echo hello | (нет args) | /bin/sh -c "echo hello" |
CMD echo hello | ls | ls |
ENTRYPOINT echo | (нет args) | echo |
ENTRYPOINT echo | hello | echo hello |
ENTRYPOINT echo + CMD hello | (нет args) | echo hello |
ENTRYPOINT echo + CMD hello | world | echo world |
ENTRYPOINT ["echo"] + CMD ["hello"] | (нет args) | echo hello |
ENTRYPOINT ["echo"] + CMD ["hello"] | world | echo world |
Best Practices
1. Используй Exec form для обоих
# Хорошо
ENTRYPOINT ["python", "/app/app.py"]
CMD ["--config", "/etc/app.conf"]
# Плохо
ENTRYPOINT python /app/app.py
CMD --config /etc/app.conf
2. ENTRYPOINT для основного процесса
# Правильно
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
# docker run image → nginx -g daemon off;
# docker run image -c /etc/nginx/nginx.conf → nginx -c /etc/nginx/nginx.conf
3. Используй wrapper script если нужна гибкость
FROM python:3.9
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["python", "app.py"]
#!/bin/bash
# docker-entrypoint.sh
set -e
# Pre-startup logic
echo "Starting app..."
# Exec the main command
exec "$@"
4. CMD для параметров, которые часто меняются
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y curl
ENTRYPOINT ["curl", "https://example.com"]
CMD ["-v"] # verbose по умолчанию
$ docker run myimage
# curl https://example.com -v
$ docker run myimage -i
# curl https://example.com -i
Вывод
Если указаны оба ENTRYPOINT и CMD:
- ENTRYPOINT — это команда, которая ВСЕГДА выполняется
- CMD — это аргументы/параметры для ENTRYPOINT
docker run image argsзаменяет CMD, но не ENTRYPOINT- Используй exec form
["cmd", "arg"]для обоих - Это позволяет гибко переопределять параметры при запуске