Open7

blitz でブログを作る

mizchimizchi

やりたいこと

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 で動いてることを確認
mizchimizchi

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'

保存できてそう

mizchimizchi

AWS RDS で postgresql インスタンスを作る

VPC の Security Group を追加

https://ap-northeast-1.console.aws.amazon.com/vpc/home

これの Security Group から新規セキュリティグループを作成。 Inbound 0.0.0.0/0:5432 を開ける。

RDS から postgres インスタンスを作成

https://ap-northeast-1.console.aws.amazon.com/rds/home

データベースの作成 >Postgres

  • 接続 > 既存のVPC セキュリティグループ > 先程作成したセキュリティグループを指定

.env に次を設定

DATABASE_URL=postgresql://<username>:<password>@<endpoint>:5432/test
SESSION_SECRET_KEY=任意の32文字以上

一番安いインスタンスを使った。本当ならAurora を使ったほうがいい。

mizchimizchi

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 連携する。

mizchimizchi

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 すると正常に初期化完了した

mizchimizchi

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
mizchimizchi

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