【アプリ準備編】Docker + Nuxt.js + MySQL + Prismaの環境を作って簡単なCRUDアプリを作ってみる

【アプリ準備編】Docker + Nuxt.js + MySQL + Prismaの環境を作って簡単なCRUDアプリを作ってみる

最近業務でReactを触れた(本当に触れた程度)のですが、結構楽しかったのとNuxt.jsも業務で使用することが多いとの噂を聞いたので、色々な勉強も兼ねて Docker + Nuxt.js + MySQL + Prisma を使ったCRUDアプリを実装してみようと思います!

今回のアプリ準備編では、Dockerを使ってNuxt.js初期アプリの作成と、Prismaを用いたテーブル定義の作成を行っていきます。

では早速やっていきましょう。

用意するもの

今回用意するファイルは2つだけになります。

.
├── Dockerfile
└── docker-compose.yml

Nuxt.jsアプリを生成した時はDockerfileと同じ階層に入れていく想定です。なのでアプリ作成後のディレクトリは下記のようになります。

.
├── .nuxt
├── components
│   ├── NuxtLogo.vue
│   └── Tutorial.vue
├── pages
中略...
├── Dockerfile
├── docker-compose.yml
└── tsconfig.json


手順1. ファイル準備

Dockerfile

DockerfileではHOST名の設定と、Nuxtアプリを作成するためのコマンドをインストールしていきます。
HOSTを0.0.0.0と設定すると、https://localhost:3000 でアプリを立ち上げることができます。

FROM node:18.12.1

# localhost:3000 で接続できるようにする
EXPOSE 3000
ENV HOST 0.0.0.0

WORKDIR /var/www/app

RUN npm install -g @vue/cli nuxt create-nuxt-app

また、今回使用するNode.jsのバージョンは、Long Term Support(長期間サポート)している 18.12.1 を選択しました。

参考:GitHub – node.js/Release

docker-compose.yml

docker-compose.yml では、Nuxt.jsとMySQLサービスをそれぞれ作成します。
MySQLの設定はこちらで行っているので、適宜自身のに変更してください。

version: "3.9"
services:
  nuxt:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - '3000:3000'
    volumes:
      - .:/var/www/app
    working_dir: /var/www/app
    command: npm run dev
    environment:
      CHOKIDAR_USEPOLLING: true
      NODE_OPTIONS: --openssl-legacy-provider
    tty: true
    links:
      - db

  db:
    image: mysql:8.0
    restart: always
    ports:
        - 3306:3306
    environment:
        # MySQLのユーザー名やパスワード 各々で設定してください
        - MYSQL_DATABASE=nuxt_db
        - MYSQL_USER=teru2teru0
        - MYSQL_PASSWORD=P@ssw0rd
        - MYSQL_ROOT_PASSWORD=P@ssw0rd

Node.jsのバージョンが17 以降だと、 Nuxt アプリ起動時に「Error: error:0308010C:digital envelope routines::unsupported」というエラーが起こってしまいます。

こちらを解決するために、環境変数に NODE_OPTIONS=--openssl-legacy-provider というのを加えています。

参考1:Node.js 17以上にした際のOpenSSL互換エラー対応
参考2:[Solved] Failed to construct transformer: Error: error:0308010C:digital envelope routines::unsupported

手順2. Dockerを立ち上げてNuxt.jsアプリを作成

ファイルの記載が終わったら、次はNuxt.jsアプリを作成します。
該当フォルダに移動し、「docker-compose build」コマンドでDocker環境のimage構築を行います。ビルドが完了後にDockerを一時的に起動させ、「npx create-nuxt-app . –overwrite-dir」でアプリを作成します。

# フォルダ移動
cd <Dockerfileがあるフォルダ>

# imageを構築
docker-compose build 

# 作成したimageからコンテナを起動し、コマンドを実行
docker-compose run --rm nuxt npx create-nuxt-app . --overwrite-dir

こちらの --overwrite-dir というオプションを外すと、Dockerfileがある階層にプロジェクトフォルダを作成し、その直下にファイルを生成します。


コマンド実行後には選択コンソールが現れ、プロジェクト名や言語などの設定を行います。
あとからでも設定の変更可能なので、一旦は画像のように設定しました。

設定が終わってしばらくすると、カレントディレクトリに様々なファイルが追加され、初期アプリの生成が完了します。

手順3. アプリ起動

それではアプリを起動させてみます。先ほどビルドしたDockerコンテナを起動させ、アプリを起動させます。

docker-compose up」コマンドを入力してDockerコンテナを起動させます。

docker-compose up

----------------------------------------------------------------------------
nuxt_app-nuxt-1  | 
nuxt_app-nuxt-1  | > practice_app@1.0.0 dev
nuxt_app-nuxt-1  | > nuxt
nuxt_app-nuxt-1  | 
nuxt_app-nuxt-1  | 
nuxt_app-nuxt-1  |    ╭────────────────────────────────────────╮
nuxt_app-nuxt-1  |    │                                        │
nuxt_app-nuxt-1  |    │   Nuxt @ v2.15.8                       │
nuxt_app-nuxt-1  |    │                                        │
nuxt_app-nuxt-1  |    │   ▸ Environment: development           │
nuxt_app-nuxt-1  |    │   ▸ Rendering:   server-side           │
nuxt_app-nuxt-1  |    │   ▸ Target:      server                │
nuxt_app-nuxt-1  |    │                                        │
nuxt_app-nuxt-1  |    │   Listening: http://172.21.0.3:3000/   │
nuxt_app-nuxt-1  |    │                                        │
nuxt_app-nuxt-1  |    ╰────────────────────────────────────────╯
nuxt_app-nuxt-1  | 
nuxt_app-nuxt-1  | ℹ Preparing project for development
nuxt_app-nuxt-1  | ℹ Initial build may take a while
nuxt_app-nuxt-1  | ℹ Discovered Components: .nuxt/components/readme.md
nuxt_app-nuxt-1  | ✔ Builder initialized
nuxt_app-nuxt-1  | ✔ Nuxt files generated ...

Dockerコンテナを立ち上げると、docker-compose.ymlに記載した「npm run dev」というコマンドが自動で実行されます。

上のような画面になりましたら、https://localhost:3000 に遷移すると画面が見れるようになると思います。

アプリ起動できました。
上に書いてあった http://172.21.0.3:3000 ですが、DockerfileでHOSTの設定をしているため、こちらに遷移しても何も表示されないです。


選択したUI Frameworkによって表示される画面が若干異なりますが、Vueの画面が現れたら勝ちです。おめでとうございます。

手順4. Prismaをインストールし、テーブル定義を作成

次はPrismaをインストールしていきます。
Prismaは、ORMライブラリで「SQLを直接書かずに、オブジェクトメソッドでDB操作ができる」もののことです。便利に使えるものという認識をしていただければと思います。

参考1:https://www.prisma.io/
参考2:https://github.com/prisma


そして、今回作成するテーブル定義がこちらになります。
DB設計が面倒だったので、 3テーブルだけ用意しました。

超簡単 ER図

会社にユーザーが所属し、ユーザーはプロフィールを持っているという仕組みのテーブルを作っていきます。

1. Prismaをインストール、初期化

先ほど 「docker-compose up」 コマンドを実行したターミナルとは別のターミナルを用意します。
用意したターミナルに、「docker-compose exec -it nuxt bash」コマンドでDockerコンテナ内に入り、Prismaのインストール、初期化をしていきます。

docker-compose exec -it nuxt bash   
# ----------- Dockerコンテナ内に入る -------------

# prismaをインストール、初期化
npm install prisma @prisma/client
npx prisma init

npm install でエラーのような赤い表示が出るかもしれませんが、特に問題ありませんので無視して大丈夫です。

2. テーブル定義とDB設定を記載

Prismaの初期化を行なうと、prisma/prisma.schemaというファイルが生成されます。こちらのファイルにテーブル定義を作っていきます。

下記のように prisma/prisma.schema を編集します。

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql" // postgresqlからmysqlに変更
  url      = env("DATABASE_URL")
}

model Company {
  id         Int      @id @default(autoincrement())
  name       String   @db.VarChar(255)
  users      User[]
}

model User {
  id        Int      @id @default(autoincrement())
  name      String
  companyId Int
  profile   Profile?
  Company   Company  @relation(fields: [companyId], references: [id])
}

model Profile {
  id     Int    @id @default(autoincrement())
  bio    String
  userId Int    @unique
  user   User   @relation(fields: [userId], references: [id])
}

今回はMySQLを使用するので、providerの箇所も変更するのを忘れないようにしましょう。

テーブル定義を書いたら、PrismaがどのDBと接続するか という情報を .envに記載する必要があります。
既に .env は作成されていると思うので、記載されているDATABASE_URLを 自身の環境に合うように変更します。

# DATABASE_URLの例)
# <使用するRDBMS>://<ユーザー>:<パスワード>@<ホスト名>:<ポート>/<DB名>
DATABASE_URL="mysql://root:P@ssw0rd@db:3306/nuxt_db"

今回はユーザーは root で行っていますがセキュリティ的にも少々問題があるので、他ユーザーで操作する場合はDBの操作権限の付与を行なってからユーザー名を変更してください。

ユーザーに権限をつける手順については、下記をお試しください。

ユーザーに特定のDBの操作権限を付ける方法

ターミナルをもう一つ用意し、「docker-compose exec -it db bash」コマンドでDBのDockerコンテナに入ります。rootユーザーでログインし、パスワードやユーザー名などそれぞれ適宜入力し、下記コマンドに実行してユーザーに権限を付与します。

docker-compose exec -it db bash   
# ----------- Dockerコンテナ内に入る -------------

# この後にパスワードを入力
mysql -u root -p

# ----------- MySQL内に入る -------------
FLUSH PRIVILEGES;
CREATE USER '<ユーザー>'@'localhost' IDENTIFIED BY '<パスワード>';
GRANT ALL ON `<DB名>`.* TO '<ユーザー>'@'localhost';

これで権限付与完了です。

3. Prismaコマンドでテーブル作成

さて、これで最後です!

準備ができたら、Prismaコマンドを実行したターミナルで、「npx prisma migrate dev –name initialization」コマンドを実行します。

# prisma.schemaに記載された テーブル定義をDBに反映させる
npx prisma migrate dev --name initialization

この npx prisma migrate dev コマンドは、prisma.schemaファイルに変更があった場合にマイグレーションSQLファイルを作成し、DBにテーブル定義を反映してくれるコマンドです。

DBの中身を見てみると、prisma.schemaに記載した3テーブルが作成されているのがわかります。すごいぜPrisma!

参考:https://www.prisma.io/docs/reference/api-reference/command-reference#prisma-migrate

アプリ準備編 まとめ

これでDBにテーブル定義を反映し終わりました!

思っていたよりも簡単にアプリ作成ができてよかったです。
次回は画面の実装と、CRUDするためのPrisma Clientの実装をやっていきたいと思います。
Nuxt.jsを触るのは初めてなので色々つまづくと思いますが頑張ってやっていきます!

この記事が誰かの役に立てますように。

Dockerカテゴリの最新記事