FROM, RUN, COPY, CMD, ENTRYPOINT
Тема дорожной карты · Docker & Containers
Эти пять инструкций покрывают около 90% реальных Dockerfile. FROM выбирает базовый образ (и начинает новую стадию сборки), RUN выполняет команду и фиксирует её результат как новый слой, COPY копирует файлы из контекста сборки, CMD задаёт аргументы по умолчанию, ENTRYPOINT — исполняемый файл. Частые ошибки: предпочитайте COPY вместо ADD (последний ещё распаковывает архивы и ходит по URL), используйте exec-форму (["nginx","-g","daemon off;"]), чтобы сигналы доходили до PID 1; CMD перезаписывается аргументами docker run ... <args>, а ENTRYPOINT остаётся. Их часто комбинируют: ENTRYPOINT ["./app"] + CMD ["--help"].
Как это работает
FROM, RUN, COPY, CMD, ENTRYPOINT хранятся как стек read-only слоёв + JSON config. docker build читает Dockerfile и создаёт по одному слою на инструкцию (RUN, COPY, ADD) — попадание в кэш пропускает работу, если родительский слой и команда не изменились. Теги (repo:tag) — изменяемые указатели; контент адресуется SHA-256 digest. Multi-stage сборки (FROM base AS builder … FROM slim … COPY --from=builder) поставляют только финальный stage, ужимая runtime-образ.
Когда применять
Сортируйте инструкции Dockerfile от наименее- к наиболее-часто-меняющимся (system deps → app deps → app source) — максимизируете попадания в кэш. Multi-stage сборки — везде, где финальный образ требует меньше, чем сборка (Go-бинарники, скомпилированные ассеты, npm-собранный JS). Закрепляйте базовые образы по digest (FROM node:22-alpine@sha256:...) для воспроизводимости — node:latest пересобирается с тем Node, что выкатили сегодня. .dockerignore держит .git, node_modules, тестовые артефакты вне build context.
Типичные ошибки
Ловушки FROM, RUN, COPY, CMD, ENTRYPOINT: изменяемый тег :latest в production (образ сегодня ≠ образ вчера); огромные образы из-за apt-get update без rm -rf /var/lib/apt/lists/* в том же RUN; убитый кэш из-за COPY . . перед RUN npm install (каждое изменение кода инвалидирует слой deps); секреты, запечённые в слой через ENV (живут в history навсегда — используйте --secret mount или build args аккуратно).