Docker для разработчиков: образы, контейнеры и Compose
Вы, вероятно, слышали о Docker и о том, как он может упростить ваш рабочий процесс разработки. Но если вы новичок в контейнерах, терминология и команды могут показаться ошеломляющими. Это руководство отсекает лишний шум и даёт практическое понимание Docker-образов, контейнеров и Compose — чтобы вы могли начать эффективно использовать их уже сегодня.
Что такое Docker и почему это важно?
Docker — это платформа, которая упаковывает ваше приложение и его зависимости в стандартизированную единицу, называемую контейнером. Контейнеры лёгкие, портативные и изолированные друг от друга, что означает, что вы можете запускать своё приложение одинаково на своём ноутбуке, на машине коллеги или на продакшн-сервере.
Ключевое преимущество? "У меня работает" становится делом прошлого. Docker гарантирует, что среда, в которой выполняется ваш код, идентична везде.
Образы и контейнеры: строительные блоки
Прежде чем начать, вам нужно понять разницу между образом и контейнером.
- Образ: Шаблон только для чтения, который содержит код вашего приложения, среду выполнения, библиотеки и зависимости. Думайте о нём как о снимке или чертеже.
- Контейнер: Запускаемый экземпляр образа. Вы можете запускать, останавливать, перемещать и удалять контейнеры. Несколько контейнеров могут работать из одного образа.
Короче говоря: образ — это рецепт, а контейнер — это блюдо, которое вы по нему готовите.
Основные команды Docker для разработчиков
Вот команды, которые вы будете использовать чаще всего:
docker pull <image>– Скачать образ из реестра, например Docker Hub.docker images– Показать все локальные образы.docker run <image>– Создать и запустить контейнер из образа.docker ps– Показать запущенные контейнеры. Добавьте-a, чтобы увидеть все контейнеры, включая остановленные.docker stop <container>– Корректно остановить запущенный контейнер.docker rm <container>– Удалить остановленный контейнер.docker rmi <image>– Удалить образ.docker exec -it <container> bash– Открыть интерактивную оболочку внутри запущенного контейнера.
Например, чтобы запустить простой веб-сервер Nginx:
docker run -d -p 8080:80 nginx
Эта команда скачивает образ nginx (если его ещё нет), запускает контейнер в фоновом режиме (-d) и сопоставляет порт 8080 на вашем хосте с портом 80 в контейнере (-p 8080:80).
Создание собственного образа с помощью Dockerfile
Чтобы упаковать ваше приложение, вы создаёте Dockerfile — текстовый файл с инструкциями. Вот простой пример для приложения на Node.js:
# Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Set the working directory
WORKDIR /usr/src/app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy the rest of the application code
COPY . .
# Expose the port the app runs on
EXPOSE 3000
# Define the command to run the app
CMD ["node", "app.js"]
Соберите образ с помощью:
docker build -t my-node-app .
Затем запустите его:
docker run -p 3000:3000 my-node-app
Упрощение многоконтейнерных приложений с помощью Docker Compose
Реальные приложения часто нуждаются в нескольких сервисах: веб-сервер, база данных, кэш и т. д. Управление ими по отдельности с помощью docker run становится утомительным. Docker Compose позволяет определять и запускать многоконтейнерные приложения с помощью YAML-файла.
Создайте файл docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Затем запустите всё с помощью:
docker compose up -d
Compose управляет сетями, томами и зависимостями за вас. Чтобы остановить и удалить контейнеры, сети и тома, выполните docker compose down.
Лучшие практики использования Docker в разработке
- Используйте .dockerignore: Исключите ненужные файлы (например,
node_modules) из контекста сборки, чтобы ускорить сборку. - Используйте многоэтапные сборки: Держите итоговый образ маленьким, отделяя зависимости времени сборки от времени выполнения.
- Фиксируйте версии: Указывайте точные теги образов (например,
node:18.16.0-alpine) для воспроизводимости. - Запускайте не от root: Создайте пользователя в вашем Dockerfile и переключитесь на него с помощью
USERдля повышения безопасности. - Используйте тома для постоянных данных: Базы данных и другие сервисы с состоянием должны хранить данные в томах, а не внутри контейнера.
Распространённые ошибки и как их избежать
- Раздутые образы: Начинайте с минимального базового образа (например, Alpine) и очищайте кэши пакетов.
- Конфликты портов: Убедитесь, что порты хоста не заняты. Используйте
docker psдля проверки. - Игнорирование логов: Используйте
docker logs <container>для отладки проблем. - Отказ от Compose для локальной разработки: Даже простые приложения выигрывают от декларативной настройки Compose.
FAQ
В чём разница между Docker-образом и контейнером?
Образ — это шаблон только для чтения, который определяет приложение и его окружение. Контейнер — это запущенный экземпляр этого образа. Вы можете создать множество контейнеров из одного образа.
Нужен ли Docker Compose для приложения с одним контейнером?
Не обязательно. Для простых приложений достаточно docker run. Однако Compose упрощает управление переменными окружения, томами и сетями даже для одного сервиса, а также упрощает масштабирование в будущем.
Как сохранить данные в Docker?
Используйте тома. Тома хранятся вне файловой системы контейнера и сохраняются даже при удалении контейнера. В Compose определите том и подключите его к пути в контейнере (например, volumes: - mydata:/var/lib/data).
Готовы оптимизировать свой рабочий процесс с Docker? Когда вам нужно проанализировать логи контейнеров, попробуйте наш Nginx Log Analyzer для быстрого разбора и визуализации данных логов — идеально подходит для отладки контейнеризованных веб-серверов.