Что такое Compose и где он живёт:
Compose V2 входит в Docker Desktop из коробки, а на Linux ставится пакетом docker-compose-plugin. Вызывается как docker compose, через пробел. Если в туториале встречается docker-compose через дефис, это старая версия на Python, она давно не развивается. Проверка:
Код: Выделить всё
docker compose versionВозьмём типичный случай: веб-приложение плюс PostgreSQL. В корне проекта создаём файл compose.yaml (имя docker-compose.yml тоже работает, но compose.yaml сейчас основное):
Код: Выделить всё
services:
app:
build: .
ports:
- "8000:8000"
environment:
DATABASE_URL: postgres://app:secret@db:5432/appdb
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 5s
timeout: 3s
retries: 10
volumes:
pgdata:Блок healthcheck вместе с condition: service_healthy решает классическую проблему: контейнер postgres стартует за секунду, но сама база готова принимать соединения чуть позже. Без этого условия app может упасть на старте с ошибкой подключения. Голый depends_on гарантирует только порядок запуска контейнеров, не готовность сервиса внутри.
Запускаем и смотрим:
Код: Выделить всё
docker compose up -d
docker compose ps
docker compose logs -f app
docker compose exec db psql -U app appdbОстановка и обновление:
docker compose stop останавливает контейнеры. docker compose down останавливает и удаляет их вместе с сетью, при этом именованные тома остаются и данные базы целы. С флагом -v тома тоже удалятся, поэтому на рабочем проекте лишний раз его не набирайте.
После правок в коде пересоберите образ:
Код: Выделить всё
docker compose up -d --buildТипичные грабли:
Первая ловушка: строка version: "3.8" в начале файла. Старые статьи начинаются с неё, но Compose V2 это поле игнорирует и пишет предупреждение. Просто не указывайте его.
Вторая: подключение к базе по localhost. Внутри контейнера app адрес localhost указывает на сам контейнер app, базы там нет. Используйте имя сервиса.
Третья: занятый порт. Если на машине уже крутится локальный PostgreSQL на 5432, проброс упадёт с ошибкой port is already allocated. Поменяйте левую часть, например "5433:5432", или вообще не публикуйте порт базы наружу: для связи между сервисами внутри одной сети проброс не нужен.
Четвёртая: правки в compose.yaml не подхватываются сами. После изменения файла выполните docker compose up -d ещё раз, Compose пересоздаст только изменившиеся сервисы.
Что усвоили:
Весь стек проекта теперь описан декларативно: один compose.yaml в репозитории заменяет страницу инструкций по запуску. Вы умеете поднимать, останавливать и пересобирать многоконтейнерное приложение и дожидаться готовности базы через healthcheck. В главе 9 займёмся размером образов и multi-stage сборкой, а в главе 10 разберём, как читать логи и отлаживать контейнеры, когда что-то пошло не так.