【Next.js】PrismaでMySQLローカル環境をDocker構築する方法

# はじめに
Next.jsとPrisma・MySQLでフルスタックアプリを作成しているが、何せPrismaを使用するのが初めて（かつDockerもプライベートでは久々）なため、DBの構築に手こずった。

そのため、備忘録的に、記事にしておこうと思う。

# Prismaとは
`Prisma`とはTypeScriptと相性がいいORマッパーである。
モダンな開発に相性がいいので、筆者も使うことにしたが、初学者ゆえの苦労があった・・・

# Dockerの設定

```env:.env
MYSQL_ROOT_PASSWORD = your_root_password
MYSQL_DATABASE = mydatabase
```

```yaml:docker-compose.yaml
version: '3'

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
    ports:
      - 3306:3306
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mysql-data:
```

このようにすることでDockerのMySQLコンテナの作成ができる。コマンドは以下である。

```
docker-compose up
```

# Prismaの設定
まずはスキーマを作成する。
スキーマとはDBのテーブルをオブジェクトにしたものだ。
（だからO(オブジェクト)/R(リレーショナル)マッパーと呼ぶ)
```scheme: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 Account {
  id                 String  @id @default(cuid())
  userId             String
  type               String
  provider           String
  providerAccountId  String
  refresh_token      String?  @db.Text
  access_token       String?  @db.Text
  expires_at         Int?
  token_type         String?
  scope              String?
  id_token           String?  @db.Text
  session_state      String?

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
  Todo          Todo[]
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime

  @@unique([identifier, token])
}

model Todo {
  id        String   @id @default(cuid())
  userId    String
  title     String
  completed Boolean  @default(false)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}
```
筆者の場合、TodoとUserを作成した。
その後、以下のコマンドで`.env`ファイルを作成する。
```
npx prisma init
```

作成されたファイルは以下となっているはずだ。
（なっていない場合、自力でURLを整える）
```.env
DATABASE_URL="mysql://root:password@localhost:3306/nextjs-prisma-graphql-codegen-dev"
```

これができたら、実際にPrismaでDB作成を行う。
以下、コマンドを実行する。
```
npx prisma migrate dev --name init
```

## DB確認
上記までの手順が正常通りに行ったら、DockerコンテナのMySQLに接続し、DBが作成されたかを確認する。

以下、コマンドを実行する。
```
docker exec -it [コンテナIDまたはコンテナ名] bash
```

これは`dockdr ps`コマンドのNAMEという列で確認できる。

そして以下でMySQLに接続する。
```
mysql -u root -p
```
このコマンド実行時、パスワードの入力が求められるため、`docker-compose.yaml`に記載したDBのパスワードを入力して接続する。

接続ができたら以下、コマンドでDB一覧を取得し、確認する。
```
show databases;
```

以上でPrismaによるMySQL環境をDockerで作成することができる。

# 参考文献
- [MySQL](https://www.prisma.io/docs/concepts/database-connectors/mysql#connection-url)
- [MySQLをPrismaで操作するフルスタックNext.jsのローカル環境をDockerで構築する](https://zenn.dev/nawa/articles/nextjs-prisma-docker-local)