Docker для разработчиков: образы, контейнеры и Compose
Вы слышали о 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-образов
Большие образы замедляют сборку, отправку и развертывание. Следуйте этим практикам, чтобы образы оставались компактными:
- Используйте официальные slim или alpine базовые образы, когда это возможно. Например,
node:18-alpineнамного меньше, чемnode:18. - Применяйте многоэтапные сборки, чтобы отделить зависимости времени сборки от времени выполнения. Это делает финальный образ минимальным.
- Объединяйте команды RUN, чтобы уменьшить количество слоев и очистить кэши менеджера пакетов в том же слое.
- Используйте файл .dockerignore, чтобы исключить ненужные файлы (например, node_modules, .git) из контекста сборки.
Вот многоэтапный 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 up -d– запуск в фоновом режиме.docker compose logs -f web– отслеживание логов сервиса.docker compose exec web sh– открытие оболочки в запущенном контейнере.docker compose down– остановка и удаление контейнеров, сетей и томов (если тома не внешние).
Когда использовать Docker Compose, а когда Kubernetes
Docker Compose идеален для локальной разработки, тестирования и небольших развертываний. Kubernetes отлично подходит для оркестрации контейнеров в кластерах для продакшена в больших масштабах. Для многих разработчиков Compose достаточно для повседневной работы, и вы можете перейти на Kubernetes, когда понадобится автомасштабирование, самовосстановление и продвинутые сетевые возможности.
| Функция | Docker Compose | Kubernetes |
|---|---|---|
| Сценарий использования | Локальная разработка, небольшие развертывания | Продакшен-кластеры |
| Сложность | Низкая | Высокая |
| Масштабирование | Вручную | Автоматически |
| Кривая обучения | Плавная | Крутая |
FAQ
В чем разница между образом и контейнером?
Образ — это шаблон только для чтения с вашим приложением и зависимостями. Контейнер — это запущенный экземпляр образа. Вы можете запустить много контейнеров из одного образа.
Как уменьшить размер Docker-образа?
Используйте меньшие базовые образы (например, Alpine), многоэтапные сборки, объединяйте команды RUN и используйте файл .dockerignore для исключения ненужных файлов.
Можно ли использовать Docker Compose в продакшене?
Да, для небольших развертываний. Для более крупных динамических сред лучше подходит Kubernetes или Docker Swarm.
Готовы оптимизировать свой рабочий процесс с Docker? Ознакомьтесь с нашим Nginx Log Analyzer для отладки и мониторинга контейнеризованных веб-серверов.