Files
docker/docs/3. Dockerfile — сборка образа и COPY.md
T
2026-05-04 11:07:31 +03:00

6.6 KiB
Raw Blame History

Зачем нужен Dockerfile

Dockerfile — это рецепт сборки образа: от какого базового образа начать, какие пакеты установить, какие файлы скопировать, какую команду запускать по умолчанию. Команда сборки:

docker build -t my-app:1.0 -f Dockerfile /path/to/context

Контекст сборки — каталог, который вы передаёте последним аргументом (часто .). В образ попадают только файлы из контекста (по правилам .dockerignore).


Минимальный Dockerfile и сборка

Готовый вариант каталога web лежит в репозитории: docker/examples/multi-service/web/ — можно собирать оттуда (docker build -t my-web:1.0 ./web из корня multi-service). Ниже — пошагово «с нуля»:

mkdir -p ~/learn-docker/web && cd ~/learn-docker/web

Содержимое Dockerfile (ниже — максимально «говорящий» вариант с комментариями; в реальном файле комментарии допустимы):

# Синтаксис Dockerfile (опционально, для BuildKit features)
# syntax=docker/dockerfile:1

# Базовый образ: лучше фиксировать мажорную версию и по возможности slim/alpine
FROM nginx:1.27-alpine

# Метаданные (удобно в docker inspect / реестрах)
LABEL org.opencontainers.image.title="Demo static site"
LABEL org.opencontainers.image.description="Nginx with baked-in HTML from COPY"

# Переменные на этапе сборки (не попадают в runtime автоматически как ENV)
ARG BUILD_DATE=unknown
LABEL build-date="${BUILD_DATE}"

# Переменные окружения внутри контейнера при запуске
ENV NGINX_ENTRYPOINT_QUIET_LOGS=1

# Рабочая директория для последующих инструкций
WORKDIR /usr/share/nginx/html

# Копирование файлов ИЗ контекста сборки В образ (ключевой способ «положить файлы в образ»)
COPY ./html/ /usr/share/nginx/html/

# Права (nginx в alpine часто от uid 101 — для продакшена уточняйте образ)
RUN chown -R nginx:nginx /usr/share/nginx/html

# Документируем порт (не открывает его само по себе на хосте — это метаданные)
EXPOSE 80

# Healthcheck — Docker помечает контейнер unhealthy при ошибках (оркестраторы могут рестартовать)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget -qO- http://127.0.0.1/ || exit 1

# Команда по умолчанию наследуется от nginx; при необходимости переопределяем:
# CMD ["nginx", "-g", "daemon off;"]

Папка html/index.html:

<!DOCTYPE html>
<html lang="ru">
<head><meta charset="utf-8"><title>Docker COPY demo</title></head>
<body><h1>Файл попал в образ через COPY</h1></body>
</html>

Сборка и запуск:

docker build -t my-web:1.0 .
docker run -d --name from-dockerfile -p 8090:80 my-web:1.0

Скриншот: этапы сборки Step ... и успешное Successfully tagged my-web:1.0.

Скриншот: браузер на порту 8090 с вашим заголовком.


.dockerignore — что не отправлять в демон при сборке

В корне контекста создайте .dockerignore, чтобы не копировать мусор и секреты:

.git
.env
*.log
node_modules
__pycache__

Скриншот: сравнение размера контекста в логе сборки до/после добавления .dockerignore (если делали большую папку).


COPY vs ADD

  • COPY — только копирование из контекста (предсказуемо, предпочтительно).
  • ADD — то же плюс распаковка локальных tar и загрузка по URL (URL почти не используют; для tar — редко).

Многоэтапная сборка (multi-stage)

Первый этап — сборка (тяжёлые компиляторы), финальный образ — только артефакт. Пример идеи: этап builder с Node, финальный — nginx со статикой.

# syntax=docker/dockerfile:1
FROM node:22-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY src ./src
RUN npm run build

FROM nginx:1.27-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80

Скриншот: docker images — финальный образ заметно меньше, чем образ с полным Node (сравните REPOSITORY/TAG и SIZE).


Передача секретов при сборке (обзорно)

Не кладите пароли в Dockerfile в открытом виде. Варианты:

  • BuildKit secret mount: RUN --mount=type=secret ... и docker build --secret id=mysecret,src=.env.
  • ARG для некритичных параметров; помните, что значения ARG могут остаться в истории слоёв, если не обнулить.

Подробности — в Dockerfile reference.


Прослойка образов: docker history

docker history my-web:1.0

Скриншот: список слоёв и размеров.


Связь с Compose

В docker-compose.yml можно указать build: . для сервиса — Compose вызовет docker build с нужным контекстом. Полный стек — в части 4 и в каталоге docker/examples/multi-service/.