Логотип PacketForge
PacketForge
Networks • Automation • Reliability
Docker для инженера: образы, контейнеры, тома, сети и контроль ресурсов
Docker 24 февраля 2026 13 минут

Docker для инженера: образы, контейнеры, тома, сети и контроль ресурсов

Контейнеризация полезна не потому, что она модная, а потому что помогает стандартизировать запуск, деплой и сопровождение. Главное — не путать её с полноценной заменой всей эксплуатационной дисциплины.

Docker часто продают как магическое средство от всех инфраструктурных проблем. На деле это просто удобный механизм упаковки и запуска приложений с предсказуемыми зависимостями. Он хорош там, где нужна воспроизводимость, быстрый старт окружения и управляемый деплой. Но чтобы контейнеры действительно помогали, полезно понимать базовые сущности и ограничения.

1. Ментальная модель: image, container, volume, network

Самая частая путаница — между образом и контейнером. Образ (image) — это шаблон файловой системы и метаданных. Контейнер — уже запущенный экземпляр этого шаблона. Том (volume) нужен для сохранения данных вне жизненного цикла контейнера. Сеть — это то, как контейнеры и внешний мир общаются между собой.

docker image ls
docker container ls
docker volume ls
docker network ls

Если в голове эта модель уложена, Docker перестаёт казаться магией. Вы начинаете видеть конкретные слои: что собирается, что запускается, где лежат данные и как трафик проходит.

2. Dockerfile: лучше простой, чем «умный»

Хороший Dockerfile стремится быть воспроизводимым и понятным. Ему не нужно делать всё на свете. Его задача — собрать нужную среду выполнения.

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ENV PYTHONUNBUFFERED=1
EXPOSE 8000

CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]

Здесь видно несколько полезных практик: сначала копируются зависимости, чтобы кешировать слой установки, потом код приложения. Не стоит тащить в образ весь домашний каталог, локальные секреты или мусор из репозитория — для этого существует .dockerignore.

3. Контейнер не должен хранить важные данные внутри себя

Это одна из ключевых идей. Если база данных пишет всё в файловую систему контейнера без volume, данные пропадут при пересоздании контейнера. Поэтому stateful-компоненты почти всегда требуют отдельного тома или внешнего managed-хранилища.

docker run -d   --name postgres   -e POSTGRES_PASSWORD=secret   -v pg_data:/var/lib/postgresql/data   postgres:16

Контейнер можно удалить и поднять заново, а volume останется. Именно так и достигается нормальная эксплуатационная устойчивость.

4. Сети Docker: почему контейнеры «видят» друг друга

По умолчанию Docker создаёт bridge-сеть. Если контейнеры находятся в одной пользовательской сети, они могут обращаться друг к другу по имени сервиса.

docker network create app_net

docker run -d --name db --network app_net postgres:16
docker run -d --name api --network app_net my-api:latest

Внутри этой сети приложение может обращаться к базе по хосту db. Это удобнее, чем шить IP-адреса в конфиги. Для продакшена важно помнить: публикация порта наружу через -p — это не то же самое, что внутренняя доступность контейнеров между собой.

5. Compose: когда нужен набор сервисов

Для локальной разработки и небольших окружений Docker Compose закрывает типовой сценарий: приложение + база + очередь + reverse proxy.

services:
  app:
    build: .
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - "8000:8000"
    depends_on:
      - db

  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - pg_data:/var/lib/postgresql/data

volumes:
  pg_data:

Главное — помнить, что depends_on не означает «сервис полностью готов». Контейнер базы может стартовать, но ещё не принимать подключения. Для этого нужны healthchecks, retry-логика на стороне приложения или явные wait-стратегии.

6. Ограничения ресурсов и наблюдаемость

Контейнер без ограничений может неожиданно съесть ресурсы хоста. Если рядом живут другие сервисы, это закончится деградацией всей машины.

docker run -d   --name worker   --cpus="1.5"   --memory="768m"   my-worker:latest

Даже если ограничения не жёсткие, полезно хотя бы понимать потребление:

docker stats
docker inspect my-container
docker logs -f my-container

Логи лучше выводить в stdout/stderr и собирать их централизованно. Когда приложение пишет в файл внутри контейнера, логирование становится менее прозрачным и хуже интегрируется в общую систему наблюдаемости.

7. Безопасность: минимум, который нельзя игнорировать

  • Не запускайте контейнеры под root без необходимости.
  • Не храните секреты в образе и в Git.
  • Используйте минимальные базовые образы.
  • Очищайте старые и неиспользуемые образы.
  • Следите за обновлениями и CVE в базовых слоях.
USER 1001:1001

Одна строка USER в Dockerfile уже делает поведение приложения безопаснее. Это не панацея, но правильное направление по умолчанию.

8. Типовые ошибки в реальной эксплуатации

  1. Контейнеры используются как VM и накапливают ручные изменения внутри себя.
  2. Volumes не настроены, данные теряются после пересоздания.
  3. Порты опубликованы наружу без необходимости.
  4. Секреты попадают в образ или в docker-compose.yml.
  5. Логи не ротируются и съедают диск на хосте.

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

9. Небольшой production-чек-лист

# что запущено
docker ps

# какие volumes есть
docker volume ls

# какие сети созданы
docker network ls

# сколько места съели образы и контейнеры
docker system df

# осторожная уборка неиспользуемого
docker system prune

С prune всегда аккуратно: сначала поймите, что именно считается неиспользуемым в вашей среде, иначе можно удалить то, что вы планировали быстро откатить.

Docker не отменяет эксплуатацию. Он просто делает её более стандартизированной, если использовать его осознанно.

Итог

Docker особенно полезен там, где нужен повторяемый запуск приложений и единый формат доставки. Но ценность контейнеризации раскрывается только в связке с хорошими практиками: отдельные volumes для данных, понятные сети, контроль ресурсов, безопасные образы, наблюдаемость и документированный деплой.