# Dockerfile

> Текстовый файл с инструкциями для сборки образа контейнера — базовый образ, копирование файлов, установка зависимостей и команда запуска.

Источник: https://llmdocs.ru/wiki/dockerfile/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Тип**: формат описания сборки образа
- **Разработчик**: Docker, Inc.
- **Появился**: 2013
- **Сборщик по умолчанию**: BuildKit (с Docker Engine 23.0, 2023)
- **Многоэтапная сборка**: с Docker 17.05 (2017)
- **Альтернативное имя**: Containerfile (Podman, Buildah)
- **Линтер**: hadolint
**Dockerfile** — текстовый файл с последовательностью инструкций, по которым [Docker](https://llmdocs.ru/wiki/docker.md) (или совместимый сборщик) собирает **образ контейнера**: с какого базового образа начать, какие файлы скопировать, какие команды выполнить и что запускать при старте контейнера. Dockerfile хранится в репозитории рядом с кодом и превращает сборку окружения в воспроизводимый, версионируемый процесс (см. [Контейнеризация](https://llmdocs.ru/wiki/containerization.md)).

Формат появился вместе с Docker в 2013 году и стал стандартом де-факто: его понимают Podman и Buildah (там он может называться `Containerfile`), kaniko, облачные сборщики и CI-системы.

## Пример

Типичный Dockerfile для веб-приложения на [Python](https://llmdocs.ru/wiki/python.md):

```dockerfile
# syntax=docker/dockerfile:1
FROM python:3.13-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1
WORKDIR /app

# сначала только зависимости — этот слой кэшируется, пока они не меняются
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

# потом код приложения
COPY . .

RUN useradd --create-home app
USER app

EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```

```bash
docker build -t myapp:1.0 .      # собрать образ из Dockerfile в текущем каталоге
docker run -p 8000:8000 myapp:1.0
```

## Основные инструкции

| Инструкция | Назначение |
|---|---|
| `FROM` | базовый образ; начинает новый этап сборки |
| `RUN` | выполнить команду при сборке (установка пакетов) |
| `COPY` | скопировать файлы из контекста сборки в образ |
| `ADD` | как `COPY`, но умеет скачивать URL и распаковывать архивы |
| `WORKDIR` | рабочий каталог для последующих инструкций |
| `ENV` | [переменная окружения](https://llmdocs.ru/wiki/environment-variables.md) в образе и контейнере |
| `ARG` | параметр, доступный только во время сборки |
| `USER` | от какого пользователя выполнять команды и запускать процесс |
| `EXPOSE` | документирует порт, который слушает приложение |
| `CMD` | команда по умолчанию при запуске контейнера |
| `ENTRYPOINT` | исполняемый файл, к которому добавляются аргументы `CMD` |
| `HEALTHCHECK` | команда проверки работоспособности |
| `LABEL` | метаданные образа |

Полное описание — в справочнике Docker.[1]

### CMD и ENTRYPOINT

`CMD` задаёт команду, которую легко заменить: `docker run myapp bash` запустит оболочку вместо приложения. `ENTRYPOINT` фиксирует исполняемый файл, а `CMD` превращается в его аргументы по умолчанию — так делают образы-утилиты. Обе инструкции лучше писать в **exec-форме** — JSON-массивом `["uvicorn", "main:app"]`. В shell-форме (`CMD uvicorn main:app`) процесс запускается через `/bin/sh -c`, оболочка становится PID 1 и не передаёт приложению сигнал `SIGTERM`, из-за чего контейнер останавливается только по тайм-ауту.

## Слои и кэш

Каждая инструкция `RUN`, `COPY` и `ADD` создаёт новый **слой** образа. Сборщик кэширует слои: если инструкция и её входные данные не изменились, слой берётся из кэша. Как только один слой меняется, все последующие пересобираются.[4] Отсюда главное правило порядка инструкций — от редко меняющихся к часто меняющимся: сначала системные пакеты, затем файл зависимостей и их установка, и только в конце — код приложения. Иначе любая правка кода заново скачивает все библиотеки.

Файл `.dockerignore` исключает из контекста сборки лишнее — `.git`, `node_modules`, `.venv`, локальные секреты, — ускоряя сборку и не давая этим файлам попасть в образ.

## Многоэтапная сборка

Компиляторы и инструменты сборки не нужны в итоговом образе. [Многоэтапная сборка](https://llmdocs.ru/wiki/multi-stage-build.md) позволяет собрать приложение в одном образе, а скопировать результат в другой, минимальный:[3]

```dockerfile
FROM golang:1.25 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /out/server ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=build /out/server /server
USER nonroot
ENTRYPOINT ["/server"]
```

Итоговый образ содержит только бинарник и занимает единицы мегабайт вместо сотен.

## BuildKit

С Docker Engine 23.0 (2023) сборку по умолчанию выполняет **BuildKit**. Он параллельно собирает независимые этапы, пропускает неиспользуемые и добавляет возможности: кэш-монтирования для менеджеров пакетов (`RUN --mount=type=cache`), безопасную передачу секретов при сборке (`RUN --mount=type=secret`), сборку под несколько архитектур (`docker buildx build --platform linux/amd64,linux/arm64`).[5] Первая строка `# syntax=docker/dockerfile:1` подключает актуальную версию синтаксиса.

## Хорошие практики

- Используйте небольшие официальные базовые образы (`-slim`, `alpine`, distroless) и фиксируйте их версии, а для полной воспроизводимости — дайджест `@sha256:...`.
- Объединяйте установку и очистку кэша пакетного менеджера в одной инструкции `RUN`: удаление файлов в следующем слое не уменьшает размер образа.
- Не запускайте процесс от root — добавьте `USER`.
- Не записывайте секреты в `ENV`, `ARG` или файлы образа: они остаются в слоях и видны любому, у кого есть образ.
- Проверяйте Dockerfile линтером hadolint[6] и сканируйте образ на уязвимости.
- Готовый образ публикуйте в [реестр](https://llmdocs.ru/wiki/container-registry.md) с осмысленными тегами — версией и хешем коммита, а не только `latest`.[2]

Формат хранения готового образа описан в статье [Образ контейнера и OCI](https://llmdocs.ru/wiki/oci-image.md), а запуск нескольких контейнеров вместе — в статье [Docker Compose](https://llmdocs.ru/wiki/docker-compose.md).

## См. также

- [Docker](https://llmdocs.ru/wiki/docker.md)
- [Образ контейнера и OCI](https://llmdocs.ru/wiki/oci-image.md)
- [Многоэтапная сборка (multi-stage)](https://llmdocs.ru/wiki/multi-stage-build.md)
- [Docker Compose](https://llmdocs.ru/wiki/docker-compose.md)
- [Container registry](https://llmdocs.ru/wiki/container-registry.md)

## Источники

1. [Docker Docs — Dockerfile reference](https://docs.docker.com/reference/dockerfile/)
2. [Docker Docs — Building best practices](https://docs.docker.com/build/building/best-practices/)
3. [Docker Docs — Multi-stage builds](https://docs.docker.com/build/building/multi-stage/)
4. [Docker Docs — Docker build cache](https://docs.docker.com/build/cache/)
5. [Docker Docs — BuildKit](https://docs.docker.com/build/buildkit/)
6. [hadolint — Dockerfile linter](https://github.com/hadolint/hadolint)
