Короткий ответ
FROM задаёт базовый образ, RUN выполняет команду во время сборки и фиксирует результат новым слоем, COPY копирует файлы с хоста в образ, CMD задаёт команду, выполняемую по умолчанию при запуске контейнера.
Как это работает подробнее
FROM указывает стартовую файловую систему и наследуемые метаданные; всё, что идёт после, добавляется слоями сверху. RUN выполняется в процессе docker build, то есть влияет только на содержимое образа, а не на поведение при запуске. COPY переносит файлы из контекста сборки (папки, переданной в docker build) в файловую систему образа. CMD не выполняется при сборке — она просто записывается в метаданные образа и запускается, когда создаётся контейнер, если не переопределена явно.
Пример кода
Dockerfile
FROM python:3.12-slim
RUN pip install --no-cache-dir flask==3.0.0
COPY app.py /app/app.py
WORKDIR /app
CMD ["python", "app.py"]Что использовать на практике
- Практика. в одном Dockerfile обычно одна инструкция
FROM(без multi-stage), несколькоRUN/COPYи одна итоговаяCMD(илиENTRYPOINT). Порядок инструкций важен для кэширования слоёв: то, что меняется редко, должно идти раньше.
Подводные камни
- Риск. пишут бизнес-логику в
RUNтам, где она должна выполняться при старте контейнера (CMD), либо наоборот ожидают, чтоCMDвыполнится во время сборки и проверит результат — это не так,CMDтолько декларируется.