## Зачем нужен 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 # Синтаксис 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`: ```html Docker COPY demo

Файл попал в образ через COPY

``` Сборка и запуск: ``` 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` со статикой. ```dockerfile # 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](https://docs.docker.com/reference/dockerfile/). --- ## Прослойка образов: `docker history` ``` docker history my-web:1.0 ``` **Скриншот:** список слоёв и размеров. --- ## Связь с Compose В `docker-compose.yml` можно указать `build: .` для сервиса — Compose вызовет `docker build` с нужным контекстом. Полный стек — в части **4** и в каталоге `docker/examples/multi-service/`.