Ответ
Инструкция CMD в Dockerfile задаёт команду и её аргументы по умолчанию, которые будут выполнены при запуске контейнера, если пользователь не укажет свою команду в docker run. В одном Dockerfile может быть только одна эффективная инструкция CMD (используется последняя).
Форматы записи:
-
Exec-форма (рекомендуется):
CMD ["executable", "param1", "param2"]- Команда выполняется напрямую, без оболочки (
/bin/sh). - Переменные окружения не интерполируются, но это более чистый сигнальный механизм (PID 1).
CMD ["nginx", "-g", "daemon off;"]
- Команда выполняется напрямую, без оболочки (
-
Shell-форма:
CMD command param1 param2- Выполняется через
/bin/sh -c. - Поддерживает подстановку переменных окружения, но хуже обрабатывает сигналы остановки.
CMD nginx -g 'daemon off;'
- Выполняется через
Взаимодействие с ENTRYPOINT:
- Если определён
ENTRYPOINT, тоCMDзадаёт аргументы по умолчанию для него. - Аргументы
CMDможно полностью переопределить при запуске контейнера.
Практический пример из моего опыта:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# ENTRYPOINT задаёт интерпретатор, CMD — скрипт по умолчанию
ENTRYPOINT ["python"]
CMD ["app.py"]
Запуск контейнера:
docker run my-app # Выполнит: python app.py
docker run my-app test_runner.py # Выполнит: python test_runner.py (CMD переопределён)