Docker для разработчиков: образы, контейнеры и Compose
Вы создали приложение, которое работает на вашей машине, но при развертывании что-то ломается. Зависимости отсутствуют, версии различаются, а конфигурация в беспорядке. Docker решает эту проблему, упаковывая ваше приложение и его окружение в единый переносимый модуль. В этой статье объясняются Docker-образы, контейнеры и Docker Compose с практическими примерами, чтобы вы могли оптимизировать процесс разработки.
Что такое Docker-образ?
Docker-образ — это шаблон только для чтения, содержащий код вашего приложения, среду выполнения, библиотеки, переменные окружения и файлы конфигурации. Представьте его как снимок окружения вашего приложения. Образы создаются из Dockerfile — текстового файла с инструкциями.
Вот простой Dockerfile для приложения на Node.js:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Каждая инструкция создает слой. Слои кэшируются, поэтому при пересборке после изменения кода выполняются только шаги, начиная с измененного слоя. Это делает сборку быстрой.
Что такое Docker-контейнер?
Контейнер — это запущенный экземпляр образа. Это изолированный процесс с собственной файловой системой, сетью и пространством процессов, но он использует ядро хост-ОС. Это делает контейнеры легковесными и быстрыми в запуске по сравнению с виртуальными машинами.
Чтобы запустить контейнер из образа:
docker run -d -p 3000:3000 --name myapp my-node-app
Эта команда запускает контейнер в фоновом режиме (-d), сопоставляет порт 3000 на хосте с портом 3000 в контейнере (-p 3000:3000) и называет его myapp.
По умолчанию контейнеры эфемерны. Любые записанные внутри данные теряются при остановке контейнера. Для сохранения данных используйте тома:
docker run -v /host/data:/app/data my-node-app
Зачем использовать Docker Compose?
Реальные приложения часто требуют нескольких сервисов: веб-сервер, база данных, кэш и т.д. Запускать каждый с помощью docker run и связывать их вручную утомительно. Docker Compose позволяет определять и запускать многоконтейнерные приложения с помощью одного YAML-файла.
Вот docker-compose.yml для приложения на 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
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7
volumes:
pgdata:
Запустите всё с помощью:
docker compose up -d
Compose создает сеть, чтобы сервисы могли обращаться друг к другу по имени (например, db, cache). Он также управляет созданием томов и порядком зависимостей.
Ключевые команды Docker для разработчиков
docker build -t myapp .– Собрать образ из Dockerfile в текущем каталоге.docker images– Показать локальные образы.docker ps– Показать запущенные контейнеры (добавьте-aдля всех).docker exec -it myapp sh– Открыть оболочку внутри запущенного контейнера.docker logs myapp– Просмотреть логи контейнера.docker compose down– Остановить и удалить контейнеры, сети и тома, определенные в Compose.
Лучшие практики использования Docker в разработке
- Используйте .dockerignore, чтобы исключить node_modules, .git и другие ненужные файлы из контекста сборки.
- Применяйте многоэтапные сборки, чтобы уменьшить размер production-образов. Например, соберите приложение на одном этапе и скопируйте только артефакты в минимальный runtime-образ.
- Фиксируйте версии в Dockerfile (например,
node:18-alpineвместоnode:latest) для воспроизводимых сборок. - Используйте тома для кода во время разработки для горячей перезагрузки:
volumes: - .:/appв Compose. - Не запускайте от имени root в production. Создайте непривилегированного пользователя в Dockerfile.
Распространенные ошибки и как их избежать
Ошибка 1: Раздутые образы. Использование полноценного базового образа ОС, такого как ubuntu, может привести к образам размером 1 ГБ и более. Используйте slim или alpine варианты.
Ошибка 2: Медленные сборки. Упорядочивайте инструкции Dockerfile от наименее к наиболее часто изменяемым. Копируйте файлы пакетов и устанавливайте зависимости до копирования исходного кода.
Ошибка 3: Потеря данных. Всегда используйте тома для баз данных. Без них данные исчезнут при удалении контейнера.
Ошибка 4: Путаница с сетью. В Compose сервисы общаются по сети по умолчанию, используя имена сервисов как имена хостов. Не используйте localhost для доступа к другому сервису.
FAQ
В чем разница между образом и контейнером?
Образ — это шаблон только для чтения; контейнер — это запущенный экземпляр этого образа. Вы можете запустить несколько контейнеров из одного образа.
Можно ли использовать Docker Compose в production?
Compose в первую очередь предназначен для разработки и тестирования. Для production рассмотрите оркестраторы, такие как Kubernetes или Docker Swarm, хотя Compose может подойти для простых развертываний.
Как обновить контейнер новым кодом?
Пересоберите образ с помощью docker build, а затем пересоздайте контейнер: docker compose up -d --build.
Готовы оптимизировать процесс разработки? Попробуйте наш Nginx Log Analyzer, чтобы быстро отлаживать логи вашего контейнеризированного веб-сервера.