Docker для разработчиков: образы, контейнеры и Compose

DevOps2026-10-07TryQuickToolBox

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

Зачем нужен Docker? Какую проблему он решает

До появления Docker развертывание приложения требовало точного соответствия окружения: конкретных версий ОС, библиотек и конфигураций. «Работает на моей машине» стало клише, потому что это было правдой. Docker решает эту проблему, упаковывая ваше приложение вместе с зависимостями в единый переносимый модуль, называемый контейнером. Контейнеры легковесны, изолированы и работают одинаково везде, где установлен Docker.

Образы и контейнеры: ключевое различие

Образ — это шаблон только для чтения, содержащий код вашего приложения, среду выполнения, библиотеки и настройки. Контейнер — это запущенный экземпляр образа. Представьте, что образ — это класс, а контейнер — объект. Вы можете запустить несколько контейнеров из одного образа, каждый из которых изолирован от других.

Как создаются образы

Образы создаются из Dockerfile — текстового файла с инструкциями. Вот минимальный пример для приложения на Node.js:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

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

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

Соберите образ и запустите контейнер:

docker build -t my-app .
docker run -p 3000:3000 my-app

Флаг -p сопоставляет порт 3000 на вашем хосте с портом 3000 в контейнере.

Лучшие практики для эффективных Docker-образов

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

Вот многоэтапный Dockerfile для приложения на Go:

# Этап сборки
FROM golang:1.21-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/main .

# Финальный этап
FROM alpine:latest
COPY --from=builder /app/main /main
CMD ["/main"]

Финальный образ содержит только скомпилированный бинарный файл и Alpine, но не инструментарий Go.

Управление данными с помощью томов

Контейнеры эфемерны; при их удалении данные теряются. Тома сохраняют данные вне жизненного цикла контейнера. Используйте их для баз данных, загрузок или любого состояния, которое должно пережить перезапуски.

docker run -v my-data:/var/lib/postgresql/data postgres

Это создает именованный том my-data, которым управляет Docker. Для разработки вы также можете смонтировать исходный код в контейнер для горячей перезагрузки:

docker run -v $(pwd):/app -p 3000:3000 my-app

Docker Compose: оркестрация нескольких контейнеров

Реальным приложениям часто требуется несколько сервисов: веб-сервер, база данных, кэш. Запускать каждый с помощью docker run утомительно и чревато ошибками. Docker Compose позволяет определять и запускать многоконтейнерные приложения с помощью одного YAML-файла.

Практический docker-compose.yml

Вот файл Compose для приложения на Node.js с PostgreSQL и Redis:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
      - REDIS_URL=redis://cache:6379
    depends_on:
      - db
      - cache
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
  cache:
    image: redis:7-alpine
volumes:
  postgres_data:

Запустите docker compose up, чтобы запустить все сервисы. Compose создает сеть по умолчанию, чтобы контейнеры могли обращаться друг к другу по имени сервиса (например, db, cache).

Основные команды Compose

Когда использовать Docker Compose, а когда Kubernetes

Docker Compose идеален для локальной разработки, тестирования и небольших развертываний. Kubernetes отлично подходит для оркестрации контейнеров в кластерах для продакшена в больших масштабах. Для многих разработчиков Compose достаточно для повседневной работы, и вы можете перейти на Kubernetes, когда понадобится автомасштабирование, самовосстановление и продвинутые сетевые возможности.

ФункцияDocker ComposeKubernetes
Сценарий использованияЛокальная разработка, небольшие развертыванияПродакшен-кластеры
СложностьНизкаяВысокая
МасштабированиеВручнуюАвтоматически
Кривая обученияПлавнаяКрутая

FAQ

В чем разница между образом и контейнером?

Образ — это шаблон только для чтения с вашим приложением и зависимостями. Контейнер — это запущенный экземпляр образа. Вы можете запустить много контейнеров из одного образа.

Как уменьшить размер Docker-образа?

Используйте меньшие базовые образы (например, Alpine), многоэтапные сборки, объединяйте команды RUN и используйте файл .dockerignore для исключения ненужных файлов.

Можно ли использовать Docker Compose в продакшене?

Да, для небольших развертываний. Для более крупных динамических сред лучше подходит Kubernetes или Docker Swarm.

Готовы оптимизировать свой рабочий процесс с Docker? Ознакомьтесь с нашим Nginx Log Analyzer для отладки и мониторинга контейнеризованных веб-серверов.