Docker для разработчиков: образы, контейнеры и Compose
Вы написали код, который работает на вашей машине, но когда коллега пытается его запустить, он сталкивается с отсутствующими зависимостями, конфликтами версий или непонятными ошибками. Docker решает эту проблему, упаковывая ваше приложение и его окружение в единый портативный модуль. В этом руководстве вы изучите основы Docker: образы, контейнеры и Compose, с практическими шагами по контейнеризации простого веб-приложения.
Что такое Docker?
Docker — это платформа для сборки, запуска и обмена приложениями в контейнерах. Контейнер — это легковесный, автономный исполняемый пакет, который включает всё необходимое для работы программного обеспечения: код, среду выполнения, системные инструменты, библиотеки и настройки. Контейнеры изолируют приложения друг от друга и от хост-системы, обеспечивая согласованность между разработкой, тестированием и производством.
Образы и контейнеры: чертёж и работающий экземпляр
Образ — это шаблон только для чтения, который определяет контейнер. Это как класс в объектно-ориентированном программировании. Контейнер — это запускаемый экземпляр образа, как объект. Вы можете создать множество контейнеров из одного и того же образа.
Образы собираются из Dockerfile — текстового файла с инструкциями. Контейнеры запускаются с помощью docker run.
Ключевые различия
| Образ | Контейнер |
|---|---|
| Шаблон только для чтения | Запускаемый экземпляр |
Собирается с помощью docker build | Запускается с помощью docker run |
| Хранится в реестре (например, Docker Hub) | Работает на хосте |
| Слоистая файловая система | Записываемый слой сверху |
Сборка вашего первого образа
Давайте контейнеризируем простое приложение на Node.js. Создайте файл с именем Dockerfile:
# Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Set the working directory
WORKDIR /app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy the rest of the application
COPY . .
# Expose the port the app runs on
EXPOSE 3000
# Define the command to run the app
CMD ["node", "server.js"]
Соберите образ с тегом:
docker build -t my-node-app .
Флаг -t задаёт имя и тег образа. Точка . в конце указывает контекст сборки (текущий каталог).
Запуск контейнеров
Запустите контейнер из вашего образа:
docker run -p 3000:3000 -d --name my-app my-node-app
-p 3000:3000: Сопоставляет порт 3000 на хосте с портом 3000 в контейнере.-d: Запускает контейнер в отсоединённом режиме (в фоновом режиме).--name my-app: Присваивает контейнеру имя для удобства ссылок.
Проверьте запущенные контейнеры с помощью docker ps. Остановите контейнер с помощью docker stop my-app.
Управление данными с помощью томов
Контейнеры эфемерны; данные внутри них теряются при удалении контейнера. Для сохранения данных используйте тома. Например, чтобы сохранить данные базы данных:
docker run -v my-db-data:/var/lib/mysql -d mysql:8
Это создаёт именованный том my-db-data, который переживает перезапуски и удаления контейнера.
Упрощение многоконтейнерных приложений с помощью Docker Compose
Реальные приложения часто требуют нескольких сервисов: веб-сервер, база данных, кэш и т. д. Docker Compose позволяет определять и запускать многоконтейнерные приложения с помощью одного YAML-файла.
Создайте docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
postgres_data:
Запустите всё с помощью:
docker compose up -d
Compose собирает образ web, запускает базу данных и соединяет их в общей сети. Директива depends_on гарантирует, что база данных запустится перед веб-сервисом.
Основные команды Docker
docker ps -a: Список всех контейнеров (включая остановленные).docker images: Список образов.docker logs my-app: Просмотр логов контейнера.docker exec -it my-app sh: Открыть оболочку внутри работающего контейнера.docker compose down: Остановить и удалить контейнеры, сети и тома, определённые в файле Compose.
Лучшие практики для разработки
- Используйте .dockerignore, чтобы исключить файлы (например, node_modules) из контекста сборки, ускоряя сборку.
- Используйте многоэтапные сборки, чтобы уменьшить размер production-образов. Например, соберите приложение на одном этапе и скопируйте только необходимые артефакты в минимальный runtime-образ.
- Фиксируйте версии в вашем Dockerfile (например,
node:18-alpineвместоnode:latest) для воспроизводимости. - Запускайте от имени непривилегированного пользователя для безопасности. Добавьте
USER nodeпосле копирования файлов.
FAQ
В чём разница между образом Docker и контейнером?
Образ — это шаблон только для чтения, который определяет приложение и его окружение. Контейнер — это запущенный экземпляр этого образа. Вы можете создать несколько контейнеров из одного образа.
Как сохранить данные в Docker?
Используйте тома. Именованные тома (например, docker run -v my-vol:/data) хранятся вне файловой системы контейнера и сохраняются при перезапусках и удалениях контейнера.
Когда следует использовать Docker Compose?
Используйте Compose, когда ваше приложение состоит из нескольких сервисов (например, веб + база данных), которые должны работать вместе. Это упрощает оркестрацию для разработки и тестирования.
Готовы контейнеризировать ваш следующий проект? Начните с написания простого Dockerfile и запуска вашего первого контейнера. Для получения дополнительных инструментов разработчика ознакомьтесь с JSON Formatter от TryQuickToolBox, чтобы проверять ответы API при тестировании ваших контейнеризированных сервисов.