【Nextjs】Cloudflare Pagesにデプロイしようとしたら超苦労したので解決策を記録する
まえがき
記事の内容
Cloudflare PagesにデプロイしようとしたらPrismaが元凶で超苦労したので記事にします。
もう少し詳しく言うとCloudflare Pagesにデプロイするために必要なEdge runtimeをPrismaで使うためには設定が必要だったことです。
これからはメインのデプロイ先をCloudflare Pagesにしようと思っているので、今後の自分に対して道標を残しておきます。
結論
結局、PrismaのドキュメントにあるDeploy to Cloudflare Workersの通りすれば、あっさり解決しました。
ただ、1から10まですべて同じようにするのではなく、自分の環境に合わせて読み替えて進めていきます。
ブログアプリを開発中
今、Markdownで投稿できるブログアプリを開発しています。
技術スタックはNext.js、TypeScript、Prisma、Supabaseです。
年末からどう (パクる) 開発するのかリサーチし始めて、年末年始休みのうちにデプロイすることを目標に開発してきました。
開発は苦労しながらもある程度、形になってきました。
デプロイから始めるアプリ開発
そんな開発している中、以下の記事を見つけて読んでみました。
確かに、最終目標はデプロイなので先にやっておくことが大事だなと納得しました。
また私が思ったのは、いざデプロイができなくなった時に開発のどの時点で何が原因なのかはっきりすることです。
実はこれまで、開発はできたのにデプロイができないなんてことが日常茶飯事でした。
私のアプリの9割9分はデプロイできていません。
だったら、先にデプロイしておけばといいじゃんとツッコミが入ると思います。
デプロイ先の選定
ただ、これまでデプロイ先の選定ができていませんでした。
Next.jsで開発してるのだったら、デプロイ先はVercelが1番無難なのは分かっています。
お試しで、以下のアプリをデプロイしています。
しかし、商用利用するなら月20ドルが必要になります。
今回のブログアプリには広告を載せて小銭を稼ごうと思っているので、月20ドルも払っていたら毎月赤字です。
そこで前々から気になっていたCloudflare Pagesを思い切って利用することにしました。
Cloudflare Pagesは無料で公開できて、それも商用利用がOKだったことです。
私の前提条件にぴったりです。
それにNext.jsのデプロイの仕方もドキュメントがあるので余裕っしょ!!とたかを括っていました。
伏兵Prisma
遅ればせながら、Cloudflareにアカウントを作成してサクッとデプロイ・・・。
ところがどっこい!!
今回の元凶、伏兵Prismaが正体を表します。
なんとPrismaが影響してデプロイできないなんて!!
ここから、開発がストップしてデプロイに苦労することになります。
ドツボにハマり冷静さをなくす
リサーチした結果、いくつかの記事を見つけました。
記事通りに試してみました。
しかし、私の実力不足でまったく解決しません。
正直、ドツボにはまってうまくいかずに冷静さを失っていました。
見つけた記事を見つめ直す
いったん落ち着いて見つけた記事を見直しました。
完全丸パクリになってしまいますが、以下の記事の冒頭の結論に答えがありました。
それがこの記事の冒頭の結論で話したDeploy to Cloudflare Workersでした。
プロジェクト名
ここから本題に入りますが、以下の複数のプロジェクトを作成します。
- Subabase
- Next.js
- Prisma Accelerate
すべて、ひとつのアプリに必要なプロジェクトです。
ただプロジェクト名がバラバラだと分からなくなります。
そこで、今回の記事ではすべてのプロジェクト名をprisma-supabase-sample
で統一します。
ちなみにプロジェクト名は自由に決めていただいて結構です。
Supabaseの設定
まずはSupabaseのデータベースの設定を行います。
この設定でPrismaの設定で必要な情報を取得します。
プロジェクトの作成
プロジェクトの作成ページは以下の通りです。
プロジェクト名を入力
統一したプロジェクト名prisma-supabase-sample
を入力します。
Database Passwordを作成
パスワードは自動生成されたものを使用します。
Database Passwordをコピー
パスワードは後で必要なのでコピーして控えておきます。
RegionをNorthest Asia(Tokyo)を選択
Create new Projectを実行
プロジェクトの設定
DashBoardに移動して、プロジェクトprisma-supabase-sampleを選択
Project Settingsに移動
Databaseの項目を選択
Connection stringからURIを選択してコピー
URIは後で必要なのでコピーして控えておきます。
Prismaの設定
以下のPrismaのドキュメントを参考に進めていきます。
プロジェクトの作成(1. Set up your application)
コマンドを実行
C3(create-cloudflare-cli)を使ってプロジェクトを作成します。
npm create cloudflare@latest
プロジェクト名入力
In which directory do you want to create your application?
と聞かれます。
統一したプロジェクト名prisma-supabase-sample
を入力します。
オプションを選択
What type of application do you want to create?
と聞かれます。
ドキュメントでは"Hello World" Worker
を選択するように指示されていますが、
ここではNext.jsのアプリを作成するのでWebsite or web app
を選択します。
フレームワークを選択
Which development framework do you want to use?
と聞かれます。
Next
(Next.js)を選択します。
その後はデフォルトのまま選択します。
Would you like to use TypeScript? › Yes
Would you like to use ESLint? › Yes
Would you like to use Tailwind CSS? › Yes
Would you like to use `src/` directory? › No
Would you like to use App Router? (recommended) › Yes
Would you like to customize the default import alias (@/\*)? › No
ESLint Pluginの導入
Do you want to use the next-on-pages eslint-plugin?
と聞かれます。
そのままyes
を選択します。
アプリケーションをデプロイ
Do you want to deploy your application?
と聞かれます。
そのままyes
を選択します。
(2. Set up Prisma)
Prismaのセットアップ
ライブラリのインストール
npm install --save-dev prisma
Prismaの初期化
npx prisma init
初期化すると以下のファイルが自動で作成されます。
.env
prisma/schema.prisma
.envの設定
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
上記のように、ファイル.env
が作成されます。
不要なコメントは削除しておきます。
- DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
+ DATABASE_URL="postgresql://postgres:[YOUR-PASSWORD]@db.apkdlvkzcbxzhrqbqiti.supabase.co:5432/postgres"
DATABASE_URL
にSupabaseの設定で取得したURIをコピペします。
またデータベースのパスワードを[YOUR-PASSWORD]と置き換えます。
schema.prisma
PrismaスキーマにPostモデルを追加
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Post {
id Int @id @default(autoincrement())
title String
content String
}
(3. Update your database schema)
データベーススキーマを更新
npx prisma migrate dev --name init
(4. Enable Accelerate in the Prisma Data Platform)
Prisma Data PlatformでAccelerateを有効にする
Prisma Data Platformアカウントにサインアップ
GitHubアカウントでサインアップします。
プロジェクトの作成
New Projectを選択します。
統一したプロジェクト名prisma-supabase-sample
を入力します。
入力したらCreate Projectを実行します。
Accelerateの設定に移動
Database connection string
Supabaseのプロジェクト設定で取得したURIを貼り付けます。
また、[YOUR-PASSWORD]の部分はSupabaseのデータベースのパスワードに置き換えます。
Region
Asia Pacific (Tokyo)を選択を選択します。
Enable Acclerate
Generate API key
API KEYをコピー
API KEYをコピーしておきます。
Prisma Clientのインスタンスを作成
最初に作成したNext.jsのプロジェクト内にprisma.ts
を作成します。
まずは、指示通りにコピペします。
import { PrismaClient } from '@prisma/client'
import { withAccelerate } from '@prisma/extension-accelerate'
const prisma = new PrismaClient().$extends(withAccelerate())
しかし、今回はPrismaClient
をインポート元を以下のように変更します。
なぜなら、Cloudflare PagesにデプロイするにはEdge runtime
が必要だからです。
- import { PrismaClient } from '@prisma/client'
+ import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'
const prisma = new PrismaClient().$extends(withAccelerate())
またプロジェクト内で参照できるようにexport
をconst prisma
の前に付け加えておきます。
import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'
- const prisma = new PrismaClient().$extends(withAccelerate())
+ export const prisma = new PrismaClient().$extends(withAccelerate())
(5. Configure the Accelerate connection string in your project)
プロジェクトでAccelerate接続文字列を構成
.env
ファイルを変更
コピーしておいたAPI KEYを.env
ファイルに追加します。
そして元々あったDATABASE_URL
はDIRECT_URL
に変更します。
# 新しいAPI KEY
+ DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlfa2V5IjoMtYzUzMTY0NTJiNygtYjU4Njk0OGVhMGE0IiwW50X2lkIjoiNWX3NlY3JldCI6IjRlZGViZE0YtNDI3Zi0MS00NzZmLWI4ND04NGE2NhYmYMzE0MmVmODc0YzRiMzgxZWNmODc0MWViMWMwMzdkMTmMDA1MjE4M2ViMmY5ZDY4MmIIsImludGVybmFsWidGVuYE3LTA5OGEwLTZhNT2NWZiOTdmJjZTRjNjhlYyJ9.JMe-4ZZfbIi_VY9eqNay-_rdMEWFKYAcFNhYPGzsgXQ"
# 元々あった`DATABASE_URL`は`DIRECT_URL`に変更
- DATABASE_URL="postgresql://postgres:[YOUR-PASSWORD]@db.apkdlvkzcbxzhrqbqiti.supabase.co:5432/postgres"
+ DIRECT_URL="postgresql://postgres:[YOUR-PASSWORD]@db.apkdlvkzcbxzhrqbqiti.supabase.co:5432/postgres"
prisma/schema.prisma
ファイルを変更
.env
ファイルを変更に合わせてdirectUrl
プロパティをdatasource
に追加します。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
+ directUrl = env("DIRECT_URL")
}
model Post {
id Int @id @default(autoincrement())
title String
content String
}
Prisma Accelerate拡張機能をインストール
以下のコマンドを実行して、Accelerate Prisma Clientをインストールします。
npm install @prisma/extension-accelerate
実行すると先ほどのエラーが解消されます。
Prisma Clientの生成(6. Generate a Prisma Client)
Accelerate用Prismaクライアントの作成
以下のコマンドを実行して、Accelerate用Prismaクライアントの作成します。
npx prisma generate --no-engine
環境変数の設定
以上でデプロイに必要な設定が終わりました。
これでデプロイ時にエラーが発生することはなくなったはずです。
ただCloudflare Pagesにデプロイした場合、.env
で設定した環境変数は読み込まれません。
そこでCloudflareのダッシュボードから環境変数の設定をする必要があります。
まずは左のサイドバーのWorkers & Pagesのドロップダウンメニュから概要を選択します。
概要のプロジェクトの一覧からprisma-supabase-sample
を選択します。
設定を選択した後、環境変数を選択します。
プロダクションの環境変数に.env
の2つの変数を追加します。
- DATABASE_URL
- DIRECT_URL
あとがき
長い工程で大変でしたが、おつかれさまでした。
今後の自分のために記録しておくのが目的ですが、皆さんの手助けになれば幸いです。
youtubeチャンネル「typescriptでフルスタックエンジニアになる」を運営しています。
Cloudflare WorkersにAPIを作成したり、Cloudflare Pagesにデプロイする前提でフォームの作り方や認証機能の使い方を動画にしています。
ぜひ、ご覧ください。
Discussion
非常に助かりました😊
こちらこそお役に立てて嬉しいです😀