Ошибка 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.