# Связывание контейнеров с помощью Docker Compose ## Введение * **Проблема:** Управление несколькими взаимосвязанными Docker-контейнерами вручную с помощью `docker run` может быть сложным и утомительным. * **Решение:** Docker Compose - инструмент для определения и запуска многоконтейнерных Docker-приложений. Он использует YAML-файл для настройки сервисов, сетей и томов. ## Что такое Docker Compose? * **Определение:** Инструмент командной строки для определения и управления многоконтейнерными Docker-приложениями. * **Принцип работы:** Читает конфигурацию из файла `docker-compose.yml` и использует Docker API для создания и управления контейнерами. * **Преимущества:** * **Упрощение управления:** Запуск, остановка и масштабирование всех сервисов приложения одной командой. * **Определение зависимостей:** Указание порядка запуска сервисов и их взаимосвязей. * **Конфигурация сети:** Автоматическое создание виртуальных сетей для взаимодействия контейнеров. * **Управление томами:** Определение постоянных хранилищ данных для сервисов. * **Воспроизводимость:** Легкое развертывание приложения в различных средах. ## Установка Docker Compose * Docker Compose обычно устанавливается вместе с Docker Desktop. * Для Linux необходимо установить его отдельно. Инструкции можно найти в официальной документации Docker. * **Проверка установки:** `docker-compose --version` ## Основной файл конфигурации: `docker-compose.yml` * **Формат:** YAML-файл, описывающий сервисы, сети и тома приложения. * **Основные секции:** * **`version`:** Указывает версию синтаксиса файла Docker Compose. Рекомендуется использовать последнюю стабильную версию. * **`services`:** Определяет отдельные сервисы (контейнеры), составляющие приложение. Каждый сервис имеет свою конфигурацию. * **`networks`:** Определяет пользовательские сети, которые могут использоваться сервисами для взаимодействия. * **`volumes`:** Определяет именованные тома, которые могут использоваться сервисами для постоянного хранения данных. ## Секция `services` * **Определение сервиса:** Каждый сервис определяется под своим именем и содержит следующие параметры: * **`image`:** Имя Docker-образа, который будет использоваться для запуска контейнера сервиса (например, `nginx:latest`, `postgres:13`). * **`build`:** Определяет параметры сборки образа из Dockerfile. Может быть указан путь к Dockerfile или контекст сборки и путь к Dockerfile внутри контекста. ```yaml build: ./web # или build: context: ./api dockerfile: Dockerfile.prod ``` * **`ports`:** Определяет порты, которые будут проброшены с хостовой машины на контейнер. Формат: `hostPort:containerPort` или `hostPort:containerPort/protocol` (tcp, udp). ```yaml ports: - "80:80" - "443:443" - "5432:5432/tcp" ``` * **`volumes`:** Определяет монтирование томов. Может быть именованный том (определенный в секции `volumes`), bind mount (путь на хосте) или анонимный том. ```yaml volumes: - db_data:/var/lib/postgresql/data - ./app:/app - my_anonymous_volume:/data ``` * **`environment`:** Определяет переменные окружения для контейнера. ```yaml environment: POSTGRES_USER: myuser POSTGRES_PASSWORD: mysecretpassword ``` * **`depends_on`:** Определяет зависимости между сервисами. Docker Compose попытается запустить зависимые сервисы перед текущим. ```yaml depends_on: - database ``` * **`restart`:** Определяет политику перезапуска контейнера при сбое (`no`, `on-failure`, `always`, `unless-stopped`). ```yaml restart: always ``` * **`networks`:** Указывает сети, к которым будет подключен сервис. ```yaml networks: - frontend - backend ``` * **`command`:** Переопределяет команду, определенную в Dockerfile. ```yaml command: ["python", "manage.py", "runserver", "0.0.0.0:8000"] ``` * **`entrypoint`:** Переопределяет entrypoint, определенный в Dockerfile. ```yaml entrypoint: ["/docker-entrypoint.sh"] ``` ## Секция `networks` * **Определение пользовательских сетей:** Позволяет создавать изолированные сети для взаимодействия контейнеров. * **Драйверы сетей:** `bridge` (по умолчанию), `host`, `overlay`, `ipvlan`, `macvlan`. * **Пример:** ```yaml networks: frontend: driver: bridge backend: driver: bridge ``` ## Секция `volumes` * **Определение именованных томов:** Абстрагирует физическое расположение тома на хосте. * **Пример:** ```yaml volumes: db_data: ``` ## Основные команды Docker Compose * **`docker-compose up`:** Создает и запускает все сервисы, определенные в `docker-compose.yml`. * `-d` или `--detach`: Запускает сервисы в фоновом режиме. * **`docker-compose down`:** Останавливает и удаляет контейнеры, сети и тома, созданные командой `up`. * `--rmi all`: Удаляет все образы, использованные сервисами. * `-v`: Удаляет именованные тома. * **`docker-compose start `:** Запускает один или несколько остановленных сервисов. * **`docker-compose stop `:** Останавливает один или несколько запущенных сервисов. * **`docker-compose restart `:** Перезапускает один или несколько сервисов. * **`docker-compose ps`:** Отображает статус запущенных сервисов. * **`docker-compose logs `:** Отображает логи указанных сервисов. * `-f` или `--follow`: Следит за логами в реальном времени. * **`docker-compose build `:** Собирает (или пересобирает) образы указанных сервисов. * **`docker-compose pull `:** Загружает образы сервисов, если они еще не существуют или если есть более новая версия. * **`docker-compose scale =`:** Масштабирует указанный сервис до заданного количества экземпляров. * **`docker-compose exec `:** Выполняет команду внутри запущенного контейнера сервиса. * **`docker-compose config`:** Проверяет и отображает объединенную конфигурацию. ## Пример `docker-compose.yml` для веб-приложения с базой данных ```yaml version: "3.8" services: web: image: nginx:latest ports: - "80:80" volumes: - ./html:/usr/share/nginx/html:ro depends_on: - app networks: - frontend app: build: ./app environment: DATABASE_URL: postgres://user:password@db:5432/mydb depends_on: - db networks: - frontend - backend db: image: postgres:13 volumes: - db_data:/var/lib/postgresql/data environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb networks: - backend networks: frontend: driver: bridge backend: driver: bridge volumes: db_data: ``` ## Описание примера: * **web сервис**: Использует образ `nginx:latest`, пробрасывает порт `80:80`, монтирует локальную директорию `./html` в `/usr/share/nginx/html` (только для чтения), зависит от сервиса `app` и подключен к сети `frontend`. * **app сервис**: Собирается из `Dockerfile`, находящегося в директории `./app`, имеет переменную окружения `DATABASE_URL` для подключения к базе данных, зависит от сервиса `db` и подключен к сетям `frontend` и `backend`. * **db сервис**: Использует образ `postgres:13`, монтирует именованный том `db_data` в `/var/lib/postgresql/data` для хранения данных, имеет переменные окружения для настройки PostgreSQL (`POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB`) и подключен к сети `backend`. * **frontend** и **backend** сети: Изолированные сети для взаимодействия веб-сервера с приложением и приложения с базой данных. * **db_data том**: Именованный том для хранения данных PostgreSQL. ## Рабочий процесс с Docker Compose 1. Создайте файл `docker-compose.yml` с описанием всех сервисов вашего приложения. 2. При необходимости создайте `Dockerfile` для ваших собственных сервисов (например, `app` в примере). 3. Запустите приложение командой `docker-compose up -d`. 4. Просматривайте логи сервисов с помощью `docker-compose logs `. 5. Останавливайте и удаляйте приложение командой `docker-compose down`. ## Заключение Docker Compose значительно упрощает управление многоконтейнерными Docker-приложениями. Файл `docker-compose.yml` является центральным элементом для определения конфигурации приложения. Понимание основных секций и команд Docker Compose необходимо для эффективной работы с несколькими связанными контейнерами.