Что означает каждая инструкция, какие у неё значения и флаги, и как писать Dockerfile правильно
FROM, RUN), но Docker их принимает в любом регистре.&&, чтобы образ был меньше.#, — комментарий. Длинную инструкцию можно переносить символом \.| Инструкция | Назначение | Пример |
|---|---|---|
| FROM | Базовый образ, с которого начинается сборка. Обязательна первой (кроме ARG перед ней). | FROM python:3.12-slim AS build |
| RUN | Выполняет команду во время сборки и фиксирует результат в слое. | RUN apt-get update && apt-get install -y curl |
| CMD | Команда по умолчанию при запуске контейнера. Переопределяется аргументами docker run. В файле допускается одна. | CMD ["nginx", "-g", "daemon off;"] |
| ENTRYPOINT | Основная команда контейнера. Аргументы из docker run добавляются к ней, а не заменяют. | ENTRYPOINT ["python", "app.py"] |
| COPY | Копирует файлы из контекста сборки в образ. | COPY requirements.txt /app/ |
| ADD | Как COPY, но умеет брать URL и распаковывать tar-архивы. Для обычного копирования используйте COPY. | ADD archive.tar.gz /opt/ |
| WORKDIR | Рабочая папка для последующих RUN, CMD, COPY. Создаётся, если её нет. | WORKDIR /app |
| ENV | Переменная окружения, сохраняется в образе и в контейнере. | ENV APP_ENV=production |
| ARG | Переменная только на этапе сборки. Можно передать через --build-arg. Видна в docker history, поэтому секреты через ARG не передавайте. | ARG VERSION=1.0 |
| EXPOSE | Документирует порт, который слушает приложение. Сам по себе порт не публикует, для этого нужен -p. | EXPOSE 8080 |
| USER | Пользователь, от имени которого выполняются RUN, CMD и ENTRYPOINT. | USER 10001:10001 |
| VOLUME | Объявляет точку монтирования для данных. Том создаётся при запуске контейнера. | VOLUME ["/var/lib/data"] |
| LABEL | Метаданные в виде ключ-значение. | LABEL maintainer="ops@example.com" version="1.0" |
| HEALTHCHECK | Команда проверки здоровья контейнера. Значение NONE отключает проверку из базового образа. | HEALTHCHECK CMD curl -f http://localhost:8080/health || exit 1 |
| SHELL | Меняет оболочку для RUN, CMD и ENTRYPOINT в shell-форме. | SHELL ["/bin/bash", "-c"] |
| STOPSIGNAL | Сигнал, которым останавливается контейнер (по умолчанию SIGTERM). | STOPSIGNAL SIGQUIT |
| ONBUILD | Инструкция, которая выполнится, когда этот образ используют как базовый в другом Dockerfile. | ONBUILD COPY . /src |
| MAINTAINER | Устарела. Используйте LABEL maintainer=.... | — |
У CMD, ENTRYPOINT и RUN есть два способа записи, и разница важна.
CMD ["node", "server.js"]. Процесс запускается напрямую, без оболочки, и получает сигналы остановки (SIGTERM) сам. Рекомендуемая форма.CMD node server.js. Команда запускается через /bin/sh -c, и сигналы может получить оболочка, а не приложение. Подстановка переменных ($HOME) работает только в ней.| Флаг | Где используется | Что делает |
|---|---|---|
| --platform=linux/amd64 | FROM | Выбор архитектуры базового образа, например для сборки под ARM. |
| --from=build | COPY | Копирует файлы из другого этапа сборки, а не из контекста. |
| --chown=app:app | COPY, ADD | Задаёт владельца скопированных файлов. |
| --chmod=755 | COPY, ADD | Задаёт права скопированных файлов. |
| --interval=30s | HEALTHCHECK | Как часто выполнять проверку (по умолчанию 30s). |
| --timeout=3s | HEALTHCHECK | Сколько ждать ответа проверки (по умолчанию 30s). |
| --start-period=10s | HEALTHCHECK | Период прогрева: ошибки в это время не засчитываются (по умолчанию 0s). |
| --retries=3 | HEALTHCHECK | Сколько неудач подряд считаются нездоровьем (по умолчанию 3). |
| --mount=type=cache,target=/root/.cache/pip | RUN | Кеш между сборками, который не попадает в слой образа. |
| --network=none | RUN | Запуск команды без сети, например для проверки. |
Проверка выполняет команду, и её код возврата решает судьбу контейнера: 0 означает «здоров», 1 — «нездоров». Статусы видны в docker ps как healthy, unhealthy или starting.
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1
Если базовый образ не содержит curl, используйте wget или проверку через свой код.
Сборка в несколько этапов позволяет компилировать код с инструментами, а в итоговый образ копировать только результат. Образ становится меньше и безопаснее, потому что компиляторов в нём нет.
FROM golang:1.23 AS build WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -o /out/app ./cmd/app FROM gcr.io/distroless/static-debian12 COPY --from=build /out/app /app USER nonroot:nonroot ENTRYPOINT ["/app"]
FROM python:3.12-slim WORKDIR /app # Сначала зависимости: этот слой кешируется, пока не меняется requirements.txt COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Код меняется часто, поэтому копируем его после зависимостей COPY . . RUN useradd --uid 10001 appuser USER 10001 EXPOSE 8000 CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Файл .dockerignore в корне контекста исключает ненужные файлы из сборки. Это ускоряет сборку и не даёт попасть в образ секретам и служебным папкам.
.git node_modules *.log .env __pycache__
docker history и docker inspect. Для секретов используйте монтирование при сборке (RUN --mount=type=secret) или переменные среды при запуске.
docker history myapp, который покажет размер каждого слоя.