Один docker run — это одна команда на один контейнер. Как только сервисов больше одного и они должны видеть друг друга по сети (приложение + БД + кэш) — проще описать всё в одном файле, чем помнить порядок docker run и вручную создавать сеть.
Современный docker compose — встроенная подкоманда Docker (плагин), не отдельный бинарник docker-compose через дефис, как было раньше. Минимальный compose.yaml:
services:
app:
image: myapp:latest
ports:
- "8080:8080"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: example
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Все сервисы одного файла автоматически попадают в общую сеть — app обращается к базе просто по имени сервиса db, без ручной настройки DNS или --link.
Запуск и остановка:
docker compose up -d
docker compose down
up -d — поднять всё в фоне, down — остановить и удалить контейнеры (тома с volumes: остаются, если не добавить -v).
Смотреть логи конкретного сервиса, а не грепать общий docker logs:
docker compose logs -f db
Важная тонкость с depends_on: он задаёт только порядок запуска контейнера, не готовность приложения внутри. db стартует раньше app, но PostgreSQL внутри него может ещё не принимать соединения в момент, когда app уже запустился и попытался подключиться. Для реальной готовности нужен healthcheck в описании сервиса db и depends_on: db: condition: service_healthy у app — иначе на первом старте app может упасть с connection refused и разбираться, что не так, придётся уже постфактум.
#docker
