無料でシュッとWebアプリを公開するため最初にする作業まとめ(Next.js App Router+Prisma ORM+Supabase)
こんにちは。わこー@funwarioisii です。
タイトルにあるスタックでクソアプリを作り散らかしています。
この記事を書きながらも、コマンドの動作確認も兼ねたクソアプリクラフトに勤しんでいます。
毎回微妙に調べて直したりしていて大変だったのですが、工程をまとめたので共有します。
多分順番にやれば15分前後でWebサービスを無料で公開できるはずです。
事前準備や想定
- VercelやSupabaseのアカウント作成済み
- VercelへのデプロイはGitHubで出来る
また、私は普段 bun を使っているので、他のパッケージマネージャーを利用されている方は適宜読み替えてください。
ローカルでのNext.jsプロジェクトの作成
Next.jsのテンプレートを展開してくれるコマンドを使ってプロジェクトを作成します。
bunx create-next-app@latest sample-pj && cd sample-pj
コマンド実行後いくつか質問されますが、プロジェクト名以外は基本的にデフォルトを想定しています。
特に何かを変えてあとに続くのセットアップで躓くことはないと思います。
Supabaseのセットアップ
Supabaseにアクセスし、新規プロジェクトを作成します。
プロジェクト作成時に設定するパスワードは、データベースのパスワードとしても使用されるため、控えておく必要があります。
Prismaのセットアップ
パッケージの追加
bun a -D prisma
スキーマ定義
mkdir prisma
touch prisma/schema.prisma
prisma/schema.prisma
に以下を書きます。
env()
としている環境変数は次のセクションで埋められます。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
}
PrismaとSupabaseの接続設定(ハマりポイント)
Supabaseを使用する場合、直接PostgreSQLに接続する場合と異なり、接続先について注意が必要です。
具体的には、以下の2つのモードを使い分ける必要があります。
- アプリケーション実行時:Transaction mode
- スキーマ変更時:Session mode
設定は簡単で環境変数に値を入れればよいです。
touch .env
として、.env
に書き込みます。
入力すべきURLの取得方法は次の説で説明しますが、次のように書くことになります。
DATABASE_URL=... # Transaction mode用
DIRECT_URL=... # Session mode用
Database URL(transaction mode)は次の形式
postgres://[db-user].[project-ref]:[db-password]@aws-0-[aws-region].pooler.supabase.com:6543/[db-name]?pgbouncer=true&connection_limit=1
Direct URL(Session mode)は次の形式
postgres://[db-user].[project-ref]:[db-password]@aws-0-[aws-region].pooler.supabase.com:5432/[db-name]
になります。2つのURLはポート番号やクエリパラメーターが違います。
これらのURLは、Supabaseのダッシュボードから取得できます。
Database URLの取得
- プロジェクトページを開く
- 画面上部(ヘッダー部)の Connect をクリック
- モーダル / Connection Stringタブ内の下部から Database URL として Transaction pooler に書かれている値を、Direct URLとして Session pooler に書かれている値を取得。
- 先程の
.env
ファイルに「パスワードを入れる」「Direct URLにはクエリを書き足す」をして追記
DBの初期化
bunx prisma migrate dev --name init
次のようなログが流れます
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "aws-0-ap-northeast-1.pooler.supabase.com:6543"
Supabase の画面上で User テーブルが作成できたことが確認できます。
Next.jsからPrismaでSupabaseにつなぐ
DBにつなぐためのクライアントを書くファイルを作ります。
mkdir src/lib
touch src/lib/prisma.ts
そこに次のように書きます。
// https://www.prisma.io/docs/orm/more/help-and-troubleshooting/help-articles/nextjs-prisma-client-dev-practices
import { PrismaClient } from "@prisma/client";
const prismaClientSingleton = () => {
return new PrismaClient();
};
declare const globalThis: {
prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();
export { prisma };
if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma;
データを表示するコードとして次の中身をsrc/app/page.tsx
に書きます。
import { prisma } from "@/lib/prisma";
export default async function Home() {
const users = await prisma.user.findMany();
return (
<div>
{JSON.stringify(users, null, 2)}
</div>
);
}
データを何も入れてなければ []
が表示されるはずです。
ここまででローカルでの開発環境は整いました。
VercelでWebサービスとして公開する
Vercelではコードをアップロードすると、ビルドしてデプロイしてくれます。
Vercelを使ってプロジェクトを作成しているとGitHubと連携して、pushされたときにその処理が走る設定が一般的な気がします。
この記事では始めやすさのためにCLIを使った方法を記述しています。
Vercel でビルドする
Vercelでビルドする場合は、next build
より前に prisma の関連ファイルを出力する必要があります。
なので、次のように設定します。
touch vercel.json
vecel.json は次のように書きます。
{
"buildCommand": "bun run prisma:generate && bun run build"
}
また、package.json
の scripts にコマンドを追記します
{
...,
"scripts": {
...,
"prisma:generate": "prisma generate"
},
}
GitHubなどと連携していればここで push すると動作が確認できるはずです。
CLIからデプロイする
簡単に確認するため、CLIからのデプロイ方法を紹介します。
vercel
コマンドを入れて実行します
bun i -g vercel
vercel --prod
Production URLがログで流れてきて、動作が確認できます!
おわりに
一旦まとめましたが、若いサービスやフレームワークなのですぐ変わることがあると思います。
更新性はあるけど雑なものとしてこちらもリンクしておきます。
Discussion