Контейнер запущен. А база уже готова?

Чем порядок запуска отличается от готовности сервиса принимать подключения.

Приложение стартует одновременно с PostgreSQL и завершается с ошибкой подключения. Через несколько секунд ручной перезапуск помогает. Это характерный признак гонки: процесс базы уже существует, но база ещё не принимает запросы.

Описать проверку готовности

В современном Docker Compose можно связать запуск зависимого сервиса с успешным healthcheck. Это фрагмент compose.yaml, а не полный файл приложения. Блок api должен также содержать ваш image или build.

yaml
services:
  db:
    image: postgres:17
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD:?Set DB_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10
  api:
    depends_on:
      db:
        condition: service_healthy

Пароль задаётся через окружение. В реальной конфигурации отдельно настройте постоянное хранение данных и параметры подключения приложения.

Что именно проверяется

pg_isready проверяет состояние приёма соединений сервером. Это не подтверждение того, что миграции применены, у пользователя есть нужные права и бизнес-запрос выполнится. Для приложения могут понадобиться дополнительные проверки.

После запуска тоже бывают сбои

Зависимость при старте не гарантирует вечную доступность базы. Приложению всё равно нужны ограниченные повторные попытки подключения, таймауты и понятные сообщения об ошибках. Не повторяйте бесконечно операцию, которая могла уже записать данные.

Как проверить

Запустите проект с остановленными контейнерами и посмотрите их состояния через docker compose ps. Затем проверьте журналы приложения: оно должно начать работу после готовности базы. Отдельно проверьте восстановление после краткого сбоя базы — это другой сценарий.

Документация

Docker Compose: Startup order ↗