DockerでPrismaのマイグレーションが実行できない
前提・実現したいこと
DockerでExpressとMySQLの環境を構築しています。
ORMマッパーとして、Prismaを使用しています。
以下のコードで、Prismaのマイグレーションを行ったのですがエラーが発生します。
npx prisma migrate dev --name init
発生している問題・エラーメッセージ
エラーメッセージ
❯ docker-compose exec app ash
/node # npx prisma migrate dev --name init
Prisma schema loaded from prisma/schema.prisma
Datasource "db": MySQL database "Nuxt-Express-TypeScript" at "db:6306"
Error: P1001: Can't reach database server at `db`:`6306`
Please make sure your database server is running at `db`:`6306`.
該当のソースコード
docker-compose.yml
version: '3.8'
volumes:
db-data:
services:
# MySQL
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: $MYSQL_DATABASE
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
TZ: $TZ
volumes:
- db-data:/var/lib/mysql
- db-data:/etc/mysql/conf.d/my.cnf
ports:
- $DB_PORT:3306
#【backend】Express
app:
build:
context: ./docker/app
environment:
TZ: $TZ
DEBUG: $BACKEND_DEBUG
DATABASE_URL: $BACKEND_DATABASE_URL
tty: true
ports:
- $BACKEND_PORT:18080
restart: always
volumes:
- $BACKEND_DIR:$BACKEND_WORK_DIR
working_dir: $BACKEND_WORK_DIR
command: [sh, -c, npm install && npm run build && npm run start]
.env
# mysql
DB_PORT = "6306"
# backend
BACKEND_PORT = "18080"
# frontend
FRONT_PORT = "3000"
STORYBOOK_PORT = "6006"
# Dockerfile <mysql>
MYSQL_DATABASE = "Nuxt-Express-TypeScript"
MYSQL_ROOT_PASSWORD = "password"
TZ = "Asia/Tokyo"
# Dockerfile <backend>
BACKEND_DIR = "./api"
BACKEND_WORK_DIR = "/node"
BACKEND_DEBUG = "api:*"
BACKEND_DATABASE_URL = "mysql://root:password@db:6306/Nuxt-Express-TypeScript"
Dockerfile
FROM node:14.15.3-alpine
WORKDIR /node
RUN apk update && apk add bash
COPY package*.json ./
RUN npm install
EXPOSE 18080
CMD npm run build && npm run start
prisma/schema.prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
}
試したこと
Sequel ProでDBにアクセスできるかどうか確認
接続確認しました。
無事接続でき、Nuxt-Express-TypeScript
というDBが作成できていることが確認できました。
DBのホスト名を変更
今回のエラーは、DBへの接続が出来ていないというものかと思います。
なので、今回はホスト名がlocalhostではなく、dbになると思うので、そこの修正を行いました。
(修正前) mysql://root:password@localhost:6306/Nuxt-Express-TypeScript
↓
(修正後) mysql://root:password@db:6306/Nuxt-Express-TypeScript
修正前も修正後もどちらもマイグレーションに失敗しました。
どこに問題があり、エラーが発生するかが分からないのでお教えいただけますと幸いです。
よろしくお願いいたします。
@bigen1925
様のご指摘に対する補足
結論から書くと、マイグレーションは成功するのですが、DBへのアクセスができません。
docker-compose.yml
を修正し、port3306で起動するように変更しました。
version: '3.8'
volumes:
db-data:
services:
# MySQL
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: $MYSQL_DATABASE
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
TZ: $TZ
volumes:
- db-data:/var/lib/mysql
- db-data:/etc/mysql/conf.d/my.cnf
#【backend】Express
app:
build:
context: ./docker/app
environment:
TZ: $TZ
DEBUG: $BACKEND_DEBUG
DATABASE_URL: $BACKEND_DATABASE_URL
tty: true
ports:
- $BACKEND_PORT:18080
restart: always
volumes:
- $BACKEND_DIR:$BACKEND_WORK_DIR
working_dir: $BACKEND_WORK_DIR
command: [sh, -c, npm install && npm run build && npm run start]
問題なく動作しています。
❯ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
docker-nuxt- docker-entrypoint.sh Up 0.0.0.0:18080->18080/t
typescript- sh -c ... cp
express_app_1
docker-nuxt- docker-entrypoint.sh Up 3306/tcp, 33060/tcp
typescript- mysqld
express_db_1
.env
の修正を行います。
# mysql
DB_PORT = "6306"
# backend
BACKEND_PORT = "18080"
# frontend
FRONT_PORT = "3000"
STORYBOOK_PORT = "6006"
# Dockerfile <mysql>
MYSQL_DATABASE = "Nuxt-Express-TypeScript"
MYSQL_ROOT_PASSWORD = "password"
TZ = "Asia/Tokyo"
# Dockerfile <backend>
BACKEND_DIR = "./api"
BACKEND_WORK_DIR = "/node"
BACKEND_DEBUG = "api:*"
- BACKEND_DATABASE_URL = "mysql://root:password@db:6306/Nuxt-Express-TypeScript"
+ BACKEND_DATABASE_URL = "mysql://root:password@db:3306/Nuxt-Express-TypeScript"
マイグレーションの実行を行います。(マイグレーションを同様の方法で試したこともあるので、このまま続けていいかい?みたいなメッセージも出ています。)
❯ docker-compose exec app ash
/node # npx prisma migrate dev --name init
Prisma schema loaded from prisma/schema.prisma
Datasource "db": MySQL database "Nuxt-Express-TypeScript" at "db:3306"
✔ - Drift detected: Your database schema is not in sync with your migration history.
The following is a summary of the differences between the expected database schema given your migrations files, and the actual schema of the database.
It should be understood as the set of changes to get from the expected schema to the actual schema.
[+] Added tables
- User
- The following migration(s) are applied to the database but missing from the local migrations directory: 20210826070628_init
We need to reset the MySQL database "Nuxt-Express-TypeScript" at "db:3306".
Do you want to continue? All data will be lost. … yes
The following migration(s) have been created and applied from new schema changes:
migrations/
└─ 20210826115115_init/
└─ migration.sql
Your database is now in sync with your schema.
✔ Generated Prisma Client (2.30.0) to ./node_modules/@prisma/client in 69ms
prisma には、 GUI でデータベース上のデータを閲覧・編集できるprisma studioを使用する。
/node # npx prisma studio
Prisma schema loaded from prisma/schema.prisma
Prisma Studio is up on http://localhost:5555
アクセスすると、エラーとなります。
また、Sequel Proでアクセスしてみます。
こちらも失敗しました。
なので、マイグレーションは成功したと思うのですが、テーブルが確認できていません。。
解決
.env
に追記を行う
# mysql
DB_PORT = "6306"
# backend
BACKEND_PORT = "18080"
+ STUDIO_PORT = "5555"
# frontend
FRONT_PORT = "3000"
STORYBOOK_PORT = "6006"
# Dockerfile <mysql>
MYSQL_DATABASE = "Nuxt-Express-TypeScript"
MYSQL_ROOT_PASSWORD = "password"
TZ = "Asia/Tokyo"
# Dockerfile <backend>
BACKEND_DIR = "./api"
BACKEND_WORK_DIR = "/node"
BACKEND_DEBUG = "api:*"
BACKEND_DATABASE_URL = "mysql://root:password@db:3306/Nuxt-Express-TypeScript"
docker-compose.yml
で5555のポートを開放させる。
version: '3.8'
volumes:
db-data:
services:
# MySQL
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: $MYSQL_DATABASE
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
TZ: $TZ
volumes:
- db-data:/var/lib/mysql
- db-data:/etc/mysql/conf.d/my.cnf
#【backend】Express
app:
build:
context: ./docker/app
environment:
TZ: $TZ
DEBUG: $BACKEND_DEBUG
DATABASE_URL: $BACKEND_DATABASE_URL
tty: true
ports:
- $BACKEND_PORT:18080
+ - $STUDIO_PORT:5555
restart: always
volumes:
- $BACKEND_DIR:$BACKEND_WORK_DIR
working_dir: $BACKEND_WORK_DIR
command: [sh, -c, npm install && npm run build && npm run start]
これで接続できました。
お答えいただきありがとうございました!