NeveTime Wiki

Docker изнутри: слои, образы и контейнеры без магии

NA

NeveTime Administrator

26 мая 2026 г.

Многие начинают знакомство с Docker по инструкции «установи и запусти». Но за кажущейся простотой скрывается стройная архитектура, понимание которой спасает от тонн дебага в проде. Сегодня я вам расскажу, что такое Docker на самом деле.

Почему контейнер — это не виртуалка

Главное отличие контейнера от виртуальной машины — отсутствие гостевой ОС. Docker использует ядро хостовой системы и изолирует процессы через механизмы Linux: namespaces и cgroups.

  • Namespaces создают отдельные представления ресурсов (PID, сеть, файловая система).
  • Cgroups ограничивают использование CPU, памяти и диска.

Поэтому контейнер стартует за секунды, а не минуты, и занимает на порядок меньше места.

Образы и их слои

Образ в Docker — это не монолитный файл, а стек слоёв, напоминающий git-коммиты. Каждая инструкция в Dockerfile создаёт новый слой.

FROM ubuntu:22.04       # слой 1
RUN apt-get update       # слой 2
RUN apt-get install -y nginx  # слой 3
COPY . /app              # слой 4

Слои кешируются: если вы изменили только COPY, первые три слоя переиспользуются. Отсюда правило: часто изменяемое ставьте в конец Dockerfile.

❗ Важно: слои иммутабельны. Когда контейнер пишет данные, используется механизм copy-on-write: сверху монтируется тонкий записываемый слой. При удалении контейнера все изменения теряются (если не использованы тома).

Как работает docker run под капотом

  1. Docker проверяет наличие образа локально → если нет, тянет из registry.
  2. Создаётся контейнер: добавляется тонкий R/W слой поверх образа.
  3. Назначаются network-интерфейсы и IP (по умолчанию bridge).
  4. Запускается команда из CMD или ENTRYPOINT.

Всё это происходит менее чем за секунду, если образ уже скачан.

Многоэтапные сборки (multi-stage builds)

Когда нам нужен только артефакт (например, скомпилированное приложение), а не вся сборочная кухня с компиляторами, спасает multi-stage:

# этап сборки
FROM golang:1.21 AS builder
WORKDIR /src
COPY . .
RUN go build -o /app ./cmd

# финальный образ
FROM alpine:3.18
COPY --from=builder /app /app
ENTRYPOINT ["/app"]

Итоговый образ получается крошечным — только бинарник и минимальный alpine.

Тома и хранение данных

Для сохранения данных между перезапусками контейнеров Docker предлагает три механизма:

Тип Применение
Volumes Полностью управляются Docker, удобны для БД и stateful-сервисов
Bind mounts Прямая привязка к папке хоста, хороши для разработки
tmpfs Хранение в памяти, для временных секретов

Использовать volumes в проде обязательно: docker run -v db_data:/var/lib/mysql mysql.

Лучшие практики для продакшена

  1. Не используйте latest тег – фиксируйте версию (nginx:1.25.3). Воспроизводимость — наше всё.
  2. Один процесс на контейнер – так проще мониторить и масштабировать.
  3. Dockerfile без секретов – никогда не копируйте .env или ключи в образ. Используйте Docker secrets или монтирование на рантайме.
  4. Запускайте от непривилегированного пользователя – в конце Dockerfile USER 1001.
  5. Сканируйте образы на уязвимостиdocker scan или Trivy в CI.
  6. Логируйте в stdout/stderr – Docker сам подхватит и передаст драйверу логирования.

Заключение

Docker — не просто «программа для запуска контейнеров», а экосистема, построенная на прозрачных принципах слоёв, изоляции и легковесной виртуализации. Зная эти основы, вы будете писать более безопасные и эффективные Dockerfile и быстрее диагностировать проблемы.

В следующей статье разберём, как встроить Docker в CI/CD на GitHub Actions и автоматизировать деплой.

← Назад ко всем статьям