Next.js, Prisma2, MySQL環境をdockerで作っていく
まずはnvmをインストール
nodeとnpmのバージョン切り替えが楽になるみたい
(Rubyでいうrbenvみたいなものか)
export NVM_DIR="$HOME/.nvm" && (
git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
cd "$NVM_DIR"
git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"
これを5行まとめてコピペ
インストール確認
command -v nvm
// nvm
nvm ls
// -> system
// iojs -> N/A (default)
// node -> stable (-> N/A) (default)
// unstable -> N/A (default)
何も入ってないので安定バージョンをインストール
nvm install --lts --latest-npm
nvm ls
// -> v14.15.4
// system
// default -> lts/* (-> v14.15.4)
// iojs -> N/A (default)
// unstable -> N/A (default)
// node -> stable (-> v14.15.4) (default)
// stable -> 14.15 (-> v14.15.4) (default)
// lts/* -> lts/fermium (-> v14.15.4)
// lts/argon -> v4.9.1 (-> N/A)
// lts/boron -> v6.17.1 (-> N/A)
// lts/carbon -> v8.17.0 (-> N/A)
// lts/dubnium -> v10.23.2 (-> N/A)
// lts/erbium -> v12.20.1 (-> N/A)
// lts/fermium -> v14.15.4
色々入った。良さそうなので最新版を使っていきます。
nvm use 14.15.4
// Now using node v14.15.4 (npm v6.14.11)
必要なファイルを作っていく
npm init -y
touch .gitignore
gitignoreにはgithubにあげる必要のない色々なファイルを書いていく
.gitignore
**/node_modules
.DS_Store
.next/
etc...
次はフロントエンドであるNextの準備
mkdir frontend
cd frontend
npm init -y
npm install --save next react react-dom @zeit/next-css
npm install --save-dev @types/node @types/react @types/react-dom typescript
touch tsconfig.json
.tsconfig.json
{
"compilerOptions": {
"allowJs": true,
"alwaysStrict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": ["dom", "es2017"],
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "esnext"
},
"exclude": ["node_modules"],
"include": ["**/*.ts", "**/*.tsx"]
}
touch next.config.js
next.config.js
const withCSS = require('@zeit/next-css')
module.exports = withCSS({})
touch next-env.d.ts
next-env.d.ts
/// <reference types="next" />
/// <reference types="next/types/global" />
mkdir components
mkdir pages
cd pages
touch index.tsx
index.tsx
import * as React from 'react'
import { NextPage } from 'next'
const IndexPage: NextPage = () => {
return <h1>Index Page</h1>
}
export default IndexPage
Next.jsの起動するためのコマンドを追加
frontend/package.json
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"type-check": "tsc"
},
次はメインディレクトリに戻ってバックエンドを構築
cd ../
npm install -g @prisma/cli
mkdir backend
cd backend
prisma init
続いてdocker-composeファイルの作成
touch docker-compose.yml
version: '3.7'
services:
mysql:
container_name: mysql
ports:
- '3306:3306'
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: prisma
MYSQL_ROOT_PASSWORD: prisma
volumes:
- mysql:/var/lib/mysql
prisma:
links:
- mysql
depends_on:
- mysql
container_name: prisma
ports:
- '5555:5555'
build:
context: backend/prisma
dockerfile: Dockerfile
volumes:
- /app/prisma
backend:
links:
- mysql
depends_on:
- mysql
container_name: backend
ports:
- '4000:4000'
build:
context: backend
dockerfile: Dockerfile
volumes:
- ./backend:/app
- /app/node_modules
- /app/prisma
frontend:
container_name: frontend
ports:
- '3000:3000'
build:
context: frontend
dockerfile: Dockerfile
volumes:
- ./frontend:/app
- /app/node_modules
- /app/.next
volumes: #define our mysql volume used above
mysql:
それぞれのディレクトリにDockerfileを用意する
cd frontend
touch Dockerfile
FROM node:14.15.4
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
RUN npm install
CMD [ "npm", "run", "dev" ]
cd ../backend
touch Dockerfile
FROM node:14.15.4
RUN npm install -g --unsafe-perm @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install
RUN prisma generate
CMD [ "npm", "start" ]
cd prisma
touch Dockerfile
FROM node:14.15.4
RUN npm install -g --unsafe-perm @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY ./ ./prisma/
CMD [ "prisma", "dev"]
prismaでMySQLを使うように変更
backend/prisma/schema.prisma
datasource db {
provider = "mysql"
url = "mysql://root:prisma@mysql:3306/prisma"
}
メインディレクトリにスクリプトを追加
package.json
"start": "docker-compose up",
"build": "docker-compose build",
"stop": "docker-compose down",
"clean": "docker system prune -af",
"clean:volumes": "docker volume prune -f",
"seed": "docker exec -it prisma npm run seed",
npm run build
// mysql uses an image, skipping
// Building prisma
// Traceback (most recent call last):
// File "compose/cli/main.py", line 67, in main
// File "compose/cli/main.py", line 126, in perform_command
// File "compose/cli/main.py", line 302, in build
// File "compose/project.py", line 468, in build
// File "compose/project.py", line 450, in build_service
// File "compose/service.py", line 1147, in build
// compose.service.BuildError: (<Service: prisma>, {'message': 'Cannot locate specified Dockerfile: Dockerfile'})
// During handling of the above exception, another exception occurred:
スクラップに追加しただけでまだDockerfile作ってなかった:sob:
気を取り直してもう一度
npm run build
// ERROR: Service 'prisma' failed to build : The command '/bin/sh -c npm install -g --unsafe-perm prisma@cli' returned a non-zero code: 1
ライブラリ名の誤字。。
You don't have any models defined in your schema.prisma, so nothing will be generated.
You can define a model like this:
スキーマ定義を一つも書いてないとダメみたい
prisma/schema.prisma
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
たくさんワーニングが出ているので後で読むメモ
npm WARN backend@1.0.0 No description
npm WARN backend@1.0.0 No repository field.
npm WARN backend@1.0.0 No description
npm WARN backend@1.0.0 No repository field.
npm WARN backend@1.0.0 No description
npm WARN backend@1.0.0 No repository field.
npm WARN frontend@1.0.0 No description
npm WARN frontend@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/watchpack-chokidar2/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
prismaが動いていない
prisma initが通ってないからかな
ここが問題だった
backend/Dockerfile
as-is
FROM node:14.15.4
RUN npm install -g --unsafe-perm @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install
RUN prisma generate
CMD [ "npm", "start" ]
to-be
FROM node:14.15.4
RUN npm install -g --unsafe-perm @prisma/cli
RUN mkdir /app
WORKDIR /app
COPY package*.json ./
COPY prisma ./prisma/
RUN npm install
RUN npx prisma generate
CMD [ "npm", "migrate:prisma" ]
CMD [ "npm", "start" ]
image作成時にprismaをgenerateしていたのはよかったが、コンテナ立ち上げでMySQLと接続した後にmigrateを通す必要があった。
なのでコマンドを追加
CMD [ "npm", "migrate:prisma" ]
migrate:prismaはpackage.jsonにコマンド作成
package.json
"migrate:prisma": "prisma migrate dev --preview-feature --name init",
ワーニングを調べていく
これはgit管理すれば解決するみたい
npm WARN backend@1.0.0 No description
npm WARN backend@1.0.0 No repository field.
npm WARN backend@1.0.0 No description
npm WARN backend@1.0.0 No repository field.
npm WARN backend@1.0.0 No description
npm WARN backend@1.0.0 No repository field.
npm WARN frontend@1.0.0 No description
npm WARN frontend@1.0.0 No repository field.
これは関連するオプションが必要なければ --no-optional
していい
npm install --no-optional
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/watchpack-chokidar2/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})