💪

MySQLをPrismaで操作するフルスタックNext.jsのローカル環境をDockerで構築する

2023/04/21に公開約4,000字

Prisma

今回初めて使い始めました。LaravelでいうEloquentで、RailsでいうActiveRecordみたいな、つまりORMです。Node.js用のORMとしては結構新しいみたいですね。

マイグレーションファイルを作ってコマンドを打つだけでテーブルを作れます。Node.jsで動くので、Next.jsのサーバーサイド用の実装からでも動かせます。

世間的には新規開発時のデータベースに PostgreSQL を採用することが多くなっている印象ですが、今回は実際のデータベースには PlanetScale を使おうと思っているので、ローカル環境では互換性のある MySQL のコンテナを立てることにします。

Dockerの設定

Next.jsとMySQL、それぞれのコンテナを作成します。楽なのでもちろんdocker-composeでまとめて管理します。

docker-compose.yml
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のセットアップ

https://www.prisma.io/docs/getting-started/setup-prisma
基本的には公式ドキュメントを読んでいればできるのですが、このままマイグレーションコマンドを実行してもPlease make sure the database user has permission to create databases.と言われ、要するに権限がなくてマイグレーションが通りません。

言われた通り、Prismaが使うMySQLのユーザーに権限を付与します。
こちらの記事を参照させていただきました。ありがとうございます!

https://zenn.dev/ms_ddd/articles/69d504a8505527

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を打ってみると、無事にテーブルが作成されたのが確認できました。

terminal
$ 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みたいな感じで、ブラウザでデータベースの状態を見られるようにします。

docker-compose.yml
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と接続するゼロフィーチャーリリースを試してみようと思います!

GitHubで編集を提案

Discussion

ログインするとコメントできます