Ошибка PrismaClientInitializationError: Can't reach database server

    При разработке приложений на Node.js с использованием Prisma и Docker вы можете столкнуться с ошибкой PrismaClientInitializationError: Can't reach database server at localhost:5432. Это сообщение указывает, что Prisma Client не может подключиться к серверу PostgreSQL. Рассмотрим основные причины и способы решения проблемы.

    Почему Prisma не может подключиться к базе данных?

    Ошибка чаще всего возникает из-за неправильной конфигурации DATABASE_URL или сетевых настроек Docker. В вашем случае приложение запускается в контейнере main, а база данных - в контейнере postgres. Использование localhost внутри контейнера указывает на сам контейнер, а не на хост или другой контейнер.

    Как исправить DATABASE_URL для Docker?

    Замените localhost на имя сервиса PostgreSQL из docker-compose.yml - postgres. Правильная строка подключения:

    DATABASE_URL="postgresql://postgres:postgres@postgres:5432/dbName?schema=public"

    Убедитесь, что файл .development.env содержит эту переменную именно с именем сервиса, а не с localhost.

    Проверка работы контейнера PostgreSQL

    Убедитесь, что контейнер postgres запущен и принимает соединения. Выполните команду:

    docker-compose ps

    Если контейнер не в состоянии Up, проверьте логи:

    docker-compose logs postgres

    Также проверьте, что порт 5432 внутри контейнера проброшен корректно (в вашем файле указан ports: - 5432:5432).

    Порядок запуска и depends_on

    В docker-compose.yml указан depends_on: - postgres. Это гарантирует, что контейнер с базой стартует раньше приложения. Однако depends_on не ждёт, пока PostgreSQL станет готов принимать запросы. Добавьте скрипт ожидания или используйте healthcheck. Пример для сервиса postgres:

    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

    Тогда в сервисе main можно указать depends_on: postgres: condition: service_healthy.

    Перегенерация Prisma Client

    Если вы меняли схему Prisma или переменные окружения, выполните внутри контейнера команду:

    docker-compose exec main npx prisma generate

    Это обновит Prisma Client в соответствии с текущей схемой и строкой подключения.

    Проверка сети Docker

    Убедитесь, что оба контейнера находятся в одной сети (по умолчанию Docker Compose создаёт общую сеть). Выполните:

    docker network ls
    docker network inspect <имя_сети>

    Контейнеры main и postgres должны быть подключены к одной сети. Если нет, добавьте в docker-compose.yml секцию networks.

    Пример исправленного docker-compose.yml

    services:
      main:
        container_name: main
        build: .
        env_file: .development.env
        volumes:
          - .:/app
          - /app/node_modules
        ports:
          - 5000:5000
          - 9229:9229
        command: npm run dev
        depends_on:
          postgres:
            condition: service_healthy
        restart: always
      postgres:
        container_name: postgres
        image: postgres:12
        env_file: .development.env
        environment:
          PG_DATA: /var/lib/postgresql/data
        ports:
          - 5432:5432
        volumes:
          - pgdata:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U postgres"]
          interval: 5s
          timeout: 5s
          retries: 5
        restart: always
    
    volumes:
      pgdata:

    После внесения изменений пересоберите и запустите контейнеры заново:

    docker-compose down
    docker-compose build
    docker-compose up

    Эти шаги помогут устранить ошибку PrismaClientInitializationError и наладить подключение к PostgreSQL в Docker.

    Часто задаваемые вопросы