Open5
Cloudflare Pages + Next.js + Prisma + NextAuthのデプロイ

デプロイがむずかしかったのでメモする
モチベーション
- 無料で個人開発アプリをデプロイしたい
なぜこの実装構成?
- フロントエンドライブラリ: 会社で使われているので勉強したかった。フロントの知識があまりないので、ディレクトリ構造など、フレームワーク側で規定してくれるのは便利そう。
- ホスティング: VercelのHobbyは広告貼れなかったりかなり厳しいので、無料枠が緩いCloudflare Pagesを使いたい
- ORM: DBにはSupabaseを使っている. 生でクエリ書きたくないので評判のいいPrismaを採用
- 認証: 認証の知識が殆ど無いので、少ない記述量で設定できるNextAuthを採用

なぜむずかしいのか
に詳しく記載されている.
- Cloudflare Pagesはedgeで動いている
- node.jsに存在するが、edgeには存在しないメソッドが存在する
- TCPソケットを使うPostgresなど、Webサーバーを前提した技術スタッツがそのままでは使えないことがある
- なので、上記に対応したバージョンの技術スタッツを使う必要がある
- Auth.jsだけなら大したことないが、ORMやDBを使うとなると工夫が必要
対策
Next.js側の対応
edgeで実行するページ(page.tsx, route.ts)に下記を追記する
export const runtime = 'edge';
Prismaの対策方法
- prisma data platformでProject作成
- supabaseのDATABASE_URLを渡し、出てきたURLを.envに記載する
- 最後に出てきた設定値をprisma.tsに記載
※ zennに書いてあるやり方。 https://www.prisma.io/docs/orm/prisma-client/deployment/edge/deploy-to-cloudflare#database-specific-considerations--examples には特に出てこないので、公式は別の方法を勧めてるのかな?(よくわかってない)
NextAuth
のSolutionの、Split Configを参照すれば良いはず。
edgeで動くように、スタンドアロンな設定値だけを持ったClientと、DBとかedgeで動かない設定値を遅延処理することで、上手く回避している?
最終的な設定
prisma.ts
import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'
const prisma = new PrismaClient().$extends(withAccelerate())
export default prisma
schma.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
import NextAuth,{ DefaultSession } from 'next-auth'
import authConfig from "./auth.config"
import { PrismaAdapter } from "@auth/prisma-adapter"
import prisma from '@/lib/prisma'
declare module 'next-auth' {
interface Session extends DefaultSession {
user: {
id: string
} & DefaultSession['user']
}
}
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
session: { strategy: "jwt" },
...authConfig,
callbacks: {
async session({ session, user }) {
if (session.user) {
session.user.id = user.id
}
return session
},
},
})
デバッグ方法
Pagesにデプロイしてからのログの計測
pnpm add wrangler --save-dev
pnpm wrangler pages deployment tail
デプロイがうまくいくか
Pagesのデプロイで行われているnpx vercel build
をローカルで実行する
自分が詰まった箇所
PrismaClientValidationError: Invalid client engine type, please use
libraryor
binary`が消えない
→ package.jsonのscripts "postinstall": "prisma generate --no-engine"の --no-engineが足りなかった
→ pgをinstallするとnode_module配下のfsライブラリを読み出してedgeで動かなくなるのでやってはいけない

関連issue
- 多分edgeで、edge未対応のauthクライアントを呼び出すとこれが現れる
関連記事

後で読みたい記事

学び・反省
- Next.jsもReactもPrismaもSupabaseもCloudflare PageもNextAuthもよくわかってない状態ですべて採用したので、問題を切り分けるのに時間がかかった
- 新しめの技術はLLMに直接聞くより、ドキュメント + issueを読んだり、それをLLMに投げた方が早い
- NextAuthのEdge Compatabilityのページはかなり前提から書かれていたので、これを読んでから、何が壊れているのか理解が早くなった
- 公式が提供してる背景ありの読み物をちゃんと読むと早い
- Cloudflare Page + NextAuth や Cloud flare Page + Prismaの構成のドキュメントは結構多いので、自分が採用しているツールの変数を減らした上でドキュメントを漁った方が早い