For

2023.1.7

Prismaでnpx prisma migrate devが「Can't reach database server at xxxx」になる場合に確認すること

環境

この記事では、Next.js用のappコンテナ、PostgreSQL用のdbコンテナを立て、appコンテナで利用するprismaからdbコンテナに接続してmigrateするという状況を例にします。

yml_____docker-compose.yml_____version: '3'

volumes:
  node_modules:
  postgres:

services:
  app:
    image: node:16.13.2
    ports:
      - 3001:3001
      - 5555:5555
    volumes:
      - .:/workspace:cached
      - node_modules:/workspace/node_modules
    working_dir: /workspace
    command: sleep infinity
  db:
    image: postgres:14
    restart: always
    environment:
      POSTGRES_DB: database
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
      - postgres:/var/lib/postgresql/data
    ports:
      - 5432:5432


問題

npx prisma migrate dev を実行すると以下のエラーが出る。

text_____terminal_____Error: P1001
Can't reach database server at `db`:`5432`
Please make sure your database server is running at `db`:`5432`.


可能性のある原因

prisma接続先のDATABASE_URLでdbコンテナをlocalhostで指定している

以下のような場合を指しています。

text_____.env_____DATABASE_URL="postgresql://postgres:password@localhost:5432/database?schema=public"


docker-composeによってappコンテナとdbコンテナが立っている状態のため、appコンテナから見たlocalhostはappコンテナということになってしまいます。
この場合は、次のように docker-compose.yml で定義したサービス名である db を使って指定します。

text_____.env_____DATABASE_URL="postgresql://postgres:password@db:5432/database?schema=public"


M1 Macを利用している

docker-compose.yml でnetworksを指定しなくてもデフォルトで同一ネットワークに属しているはずですが、M1 Macの場合はこれを明示的に指定することで解消する場合があるようです。

処理がタイムアウトしている

上記に該当しなかった場合、単純にmigrateの処理がタイムアウトしている可能性があります。
私の場合はこちらが原因のようでした。
タイムアウトした旨がエラーに表示されないため、処理が数秒でタイムアウト判定となってしまうということを知らないとタイムアウトに気づくことが難しいです。
また、なにも変えていないのにmigrateが成功するときと失敗するときがある場合はタイムアウトが濃厚です。
タイムアウトが疑わしい場合は以下のように DATABASE_URL でクエリパラメータを指定することで解消が期待できます。

text_____.env_____DATABASE_URL="postgresql://postgres:password@db:5432/database?schema=public&connect_timeout=300"