blitz でブログを作る
やりたいこと
blitz.js を AWS RDS の postgresql に繋いで vercel にデプロイする。
blitz の実体は next.js なのでほぼそのまま動くが、Vercel はDBを持たないので、今回はRDSを使う。
プロジェクトの作成
npm install -g blitz
blitz new blitz-blog
# React Final Form を選択
cd blitz-blog
blitz start
# http://localhost:3000 で動いてることを確認
docker-compose の設定
デフォルトだと sqlite を使うが、本番に近づけたいので postgres をローカルに建てる。
そのための docker-compose.yaml
version: "3.1"
services:
db:
image: postgres:13-alpine
container_name: blitz-blog-postgres
ports:
- "5432:5432"
restart: always
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
POSTGRES_DB: testdb
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:
docker-compose up -d
これでコンテナが立った。
db/schema.prisma を編集して sqlite から postgresql を使うように変更
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
.env.local に docker の postgres につなぎに行く設定をする
DATABASE_URL=postgresql://admin:password@localhost:5432/testdb
Migration を実行
$ blitz db migrate save --name init
再度起動。
$ blitz start
この状態でログインしてみる。ユーザ名、password を入力して、この状態になったら成功
Ctrl-Cで一回実行を中断し、ここで blitz console を使ってみる
$ blitz console
⚡️ > await db.user.findMany({})
[
{
id: 1,
createdAt: 2020-11-28T09:23:16.730Z,
updatedAt: 2020-11-28T09:23:16.731Z,
name: null,
email: 'miz404@gmail.com',
hashedPassword: '...',
role: 'user'
保存できてそう
AWS RDS で postgresql インスタンスを作る
VPC の Security Group を追加
これの Security Group から新規セキュリティグループを作成。 Inbound 0.0.0.0/0:5432 を開ける。
RDS から postgres インスタンスを作成
データベースの作成 >Postgres
- 接続 > 既存のVPC セキュリティグループ > 先程作成したセキュリティグループを指定
.env
に次を設定
DATABASE_URL=postgresql://<username>:<password>@<endpoint>:5432/test
SESSION_SECRET_KEY=任意の32文字以上
一番安いインスタンスを使った。本当ならAurora を使ったほうがいい。
Vercel にデプロイ
blitz.config.js で serverless mode に設定
const { sessionMiddleware, unstable_simpleRolesIsAuthorized } = require("@blitzjs/server")
module.exports = {
target: "serverless",
middleware: [
sessionMiddleware({
unstable_isAuthorized: unstable_simpleRolesIsAuthorized,
}),
],
}
vercel.json に 日本リージョンをセット
{
"regions": ["hnd1"]
}
デプロイする
$ vercel
これでvercel にデプロイで来たら設定完了。
Vercel CI/CD
GitHub でリポジトリを作る。
$ gh repo create mizchi/blitz-blog
Vercel から GitHub 連携する。
docker の postgresql のバージョンを修正
RDS で使える postgresql の最新が 12.4 だったので、docker-compose.yaml を12.4 に合わせる。
docker-compose down & docker-compose up -d
してから blitz db migrate するとエラー。
$ blitz db migrate 24s 345ms
Environment variables loaded from /Users/mizchi/gh/github.com/mizchi/blitz-blog/.env
Prisma schema loaded from db/schema.prisma
Error: P1001: Can't reach database server at `localhost`:`5432`
docker-compose logs みると前方互換性がないみたい
blitz-blog-postgres | 2020-11-29 02:49:43.888 UTC [1] FATAL: database files are incompatible with server
blitz-blog-postgres | 2020-11-29 02:49:43.888 UTC [1] DETAIL: The data directory was initialized by PostgreSQL version 13, which is not compatible with this version 12.4.
blitz-blog-postgres |
blitz-blog-postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
なのでdocker のボリュームを消すことにする。
$ docker volume ls # 対応するdbdata を探す
$ docker volume rm blitz-blog_dbdata
この状態で blitz db migrate
すると正常に初期化完了した
Chakra UI
今回は Chakra を使う
$ yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
app/pages/_app.tsx
import { ChakraProvider } from "@chakra-ui/react"
// ... getLayout を囲う
<ChakraProvider>{getLayout(<Component {...pageProps} />)}</ChakraProvider>
app/pages/index.tsx
import Layout from "app/layouts/Layout"
import { Heading, Box } from "@chakra-ui/react"
function Home() {
return (
<Box>
<Heading>Blitz Blog</Heading>
</Box>
)
}
Home.getLayout = (page) => <Layout title="Home">{page}</Layout>
export default Home
Article モデルの追加
モデルを追加する前に、まず User の id を uuid にしたいので、db/schema.prisma を修正
model User {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String?
email String @unique
hashedPassword String?
role String @default("user")
sessions Session[]
Article Article[]
}
model Session {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime?
handle String @unique
user User? @relation(fields: [userId], references: [id])
userId String?
hashedSessionToken String?
antiCSRFToken String?
publicData String?
privateData String?
}
blitz db migrate --name fix-id
する
次に、Article を生成
blitz gnerate all articles title:String content:String belongsTo:User
db/schema.prisma に追加された Article を次のように修正
model Article {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
content String
user User @relation(fields: [userId], references: [id])
userId String
}
blitz db migrate --name add-article