MySQLをPrismaで操作するフルスタックNext.jsのローカル環境をDockerで構築する
Prisma
今回初めて使い始めました。LaravelでいうEloquentで、RailsでいうActiveRecordみたいな、つまりORMです。Node.js用のORMとしては結構新しいみたいですね。
マイグレーションファイルを作ってコマンドを打つだけでテーブルを作れます。Node.jsで動くので、Next.jsのサーバーサイド用の実装からでも動かせます。
世間的には新規開発時のデータベースに PostgreSQL を採用することが多くなっている印象ですが、今回は実際のデータベースには PlanetScale を使おうと思っているので、ローカル環境では互換性のある MySQL のコンテナを立てることにします。
Dockerの設定
Next.jsとMySQL、それぞれのコンテナを作成します。楽なのでもちろんdocker-compose
でまとめて管理します。
version: "3.9"
services:
app:
build: ./docker/nextjs
volumes:
- ./src:/data
tty: true
init: true
# working_dir: /アプリ名
volumes:
- ./src:/アプリ名
ports:
- "ポート番号:ポート番号"
db:
build: ./docker/mysql
volumes:
- db-store:/var/lib/mysql
env_file:
- ./src/.env
volumes:
db-store:
もう少しいいやり方があるかもしれませんが、僕の場合はいつもNext.jsコンテナのワーキングディレクトリをコメントアウトしておき、next-create-app
が終わった後外すことで、起動してコンテナに入ったらすぐにアプリケーションのルートディレクトリに入れるようにしています。
MySQLのDockerfileは、Laravelの環境を構築していたときにお世話になっていたucan-labさんのQiitaの記事を引き続き参照させていただきました。
Prismaのセットアップ
Please make sure the database user has permission to create databases.
と言われ、要するに権限がなくてマイグレーションが通りません。
言われた通り、Prismaが使うMySQLのユーザーに権限を付与します。
こちらの記事を参照させていただきました。ありがとうございます!
db
コンテナに入ってrootユーザーでMySQLへログインし、Prismaが使用するアカウントに権限を与えます。
grant create, alter, drop, references on *.* to `ユーザー名`@`%`;
あとはドキュメント(今回なら右上のプルダウンからMySQL
を選択して)を読みながら、今回のプロジェクトではYarnを使っているので、以下コマンドでインストール・初期化を実行。
yarn add -D prisma
yarn prisma init
生成されるschema.prisma
をとりあえずこのようにします。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
環境変数はこんな感じの構成。
DATABASE_URL="mysql://ユーザー名:パスワード@db:3306/データベース名"
Laravelのときもそんな感じでしたが、localhost
ではなくサービス名のdb
を指定してMySQLのコンテナと疎通を行います。localhost
は基本的に「自分(コンテナ)自身」のオリジンなので、よそのコンテナとの通信には使えないのです。
これらの用意が済んだらマイグレーションを実行。
yarn prisma migrate dev --name init
MySQLのコンテナに入ってSQLを打ってみると、無事にテーブルが作成されたのが確認できました。
$ mysql -u ユーザー名 -p
$ Enter password: パスワード
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 70
Server version: 8.0.29 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
$ mysql> use データベース名
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
$ mysql> show tables;
+--------------------+
| Tables_in_データベース名 |
+--------------------+
| User |
| _prisma_migrations |
+--------------------+
2 rows in set (0.00 sec)
DBにログインせずにデータベースを見られるようにする
phpMyAdminみたいな感じで、ブラウザでデータベースの状態を見られるようにします。
version: "3.9"
services:
app:
build: ./docker/nextjs
volumes:
- ./src:/data
tty: true
init: true
working_dir: /アプリ名
volumes:
- ./src:/アプリ名
ports:
- "ポート番号:ポート番号"
- "5555:5555" # 👈 追記
db:
build: ./docker/mysql
volumes:
- db-store:/var/lib/mysql
env_file:
- ./src/.env
volumes:
db-store:
Prisma Studio を使うため、Next.jsのコンテナで5555番ポートを開けます。
あとはコンテナでコマンドを実行。
yarn prisma studio
localhost:5555
をブラウザで開くと、いい感じな UI でUser
テーブルを表示することができました🎉
まとめ
個人開発のスモールスタートや小規模なアプリケーションなど、なるべく低コストでフルスタックに開発する場合の選択肢としては、フルスタックNext.jsとデータベースの組み合わせは現状かなりベターな構成だと思われます。
本番環境にはGCPを使う予定なので、次はGAEにデプロイしてPlanetScaleと接続するゼロフィーチャーリリースを試してみようと思います!
Discussion