Next.jsにSupabase, Prisma初期設定手順書
バイブコーディングでSupabase, Prisma初期設定をお願いしたがいろいろダメダメだったので、結局自分で調べて自力設定した。備忘録。
※ 使用ツール:
Cursor: Version 2.2.44
Node.js: 22.20.0
OS: Windows_NT x64 10.0.26220
WSL: version 2.6.3.0
前提条件
すでにSupabaseにプロジェクトを作成済み
ステップ1: 必要なパッケージをインストール
- Prisma関連 (prisma(CLI): マイグレーション、スキーマ生成、Prisma Studioなど開発時のみ使用 → devDependencies
npm install prisma --save-dev
- Prisma関連 (@prisma/client: アプリケーションの実行時にデータベースへ接続するために必要 → dependencies
npm install prisma @prisma/client
- Supabase関連(「Supabase Client」 を使うためのライブラリ。prisma.user.findMany() のようにPrisma操作だけなら必要ない。※必要なケース:認証 (Auth)、ストレージ、リアルタイム機能
npm install @supabase/supabase-js @supabase/ssr
- PostgreSQLクライアント(PostgreSQLクライアント(開発用)
npm install -D pg
ステップ2: Supabaseの接続情報を取得
Supabaseダッシュボードで以下の情報を取得:
2-1. Database URL(2種類)
Settings → ヘッダーにあるConnectボタン
- Transaction Pooling(ポート6543)- アプリケーション用
- Direct Connection(ポート5432)- マイグレーション用
2-2. API Keys
Settings → API Keys
- Project URL
- anon public key
- service_role key(セキュアに管理)
ステップ3: 環境変数ファイルを作成
.envファイルを作成(Prisma用)
[YOUR_PASSWORD] |
Supabaseプロジェクト作成時に設定したパスワード |
|---|---|
[YOUR_PROJECT_REF] |
例:Project URL https://ilok;aafpaiieadjfka.supabase.co のilok;aafpaiieadjfkaの部分 |
[REGION] |
aws-0-ap-north-1とか |
# プロジェクトルートに.envファイルを作成
.envに以下を記載:
# Direct Connection(マイグレーション時のみ使用)- IPv4アドレスに後で変更
DIRECT_URL="postgresql://postgres:[YOUR_PASSWORD]@db.[YOUR_PROJECT_REF].supabase.co:5432/postgres?sslmode=require"
# Transaction Pooling(アプリケーション用)
DATABASE_URL="postgresql://postgres.[YOUR_PROJECT_REF]:[YOUR_PASSWORD]@[REGION].pooler.supabase.com:6543/postgres?pgbouncer=true"
.env.localファイルを作成(Next.js用)
.env.localに以下を記載:
# Supabase API設定
NEXT_PUBLIC_SUPABASE_URL=https://[YOUR_PROJECT_REF].supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=[YOUR_ANON_KEY]
SUPABASE_SERVICE_ROLE_KEY=[YOUR_SERVICE_ROLE_KEY]
# データベース接続(.envと同じ)
DATABASE_URL="postgresql://postgres.[YOUR_PROJECT_REF]:[YOUR_PASSWORD]@aws-1-ap-south-1.pooler.supabase.com:6543/postgres?pgbouncer=true"
.gitignoreに追加
# .gitignoreに以下を追加(既にあれば不要) echo ".env" >> .gitignore echo ".env.local" >> .gitignore
ステップ4: 手元の開発環境をIPv6対応にする(重要)
WindowsのWSL環境はデフォルトでIPv6対応になっていない。SupabaseのDIRECT_URL(Direct Connection)はIPv4アドレスを持っていないのでIPv6対応にする必要がある(Macの場合は問題ないので本ステップはスルーで)。
1: WSLを最新版にアップデートする
まずWSLのバージョンが 2.0.0以上 である必要がある。
Windows PowerShellを「管理者として実行」し、以下のコマンドを入力。
wsl --update wsl --version
※ wsl --version で表示されるバージョンを確認。2.0.0以上ならOK。
2: .wslconfig ファイルを作成・編集する
Windows側のユーザーフォルダ直下に設定ファイル(C:\Users\<ユーザー名>\.wslconfig)を作成し、ミラーモードを有効にする。
-
Win + Rを押し、%USERPROFILE%と入力してフォルダを開く。 - その場所に
.wslconfigという名前のファイルを作成(既にある場合は開く)。 - 以下の内容を貼り付けて保存。
[wsl2]
networkingMode=mirrored
ipv6=true
3: WSLを再起動する
設定を反映させるため、WSLを一度完全にシャットダウン。PowerShellで以下を実行。
wsl --shutdown
その後、Ubuntuを再び起動。
4: Ubuntu側でIPv6を確認する
Ubuntuのターミナルを開き、IPv6アドレスが割り当てられているか、通信ができるかを確認。
-
IPアドレスの確認:
ip addr showinet6で始まるグローバルアドレスが表示されていれば成功。 -
疎通確認:
ping6 google.com応答があれば、IPv6での通信が確立されている。
ステップ5: Prismaを初期化
Prismaを初期化(既存のschema.prismaがあれば上書き確認される)
npx prisma init
ステップ6: Prisma Schemaを設定
prisma/schema.prismaをみなさまのプロジェクトに合わせて良しなに編集設定。以下は例:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
//url = env("DATABASE_URL") 接続URL設定は既にprisma.config.tsで管理されているためここでは設定しない
}
// 例: ユーザーモデル
model User {
id String @id @default(uuid()) @db.Uuid
clerkId String @unique
email String @unique
username String @unique @db.VarChar(50)
displayName String @map("display_name") @db.VarChar(50)
bio String? @db.Text
profileImageUrl String? @map("profile_image_url") @db.VarChar(255)
coverImageUrl String? @map("cover_image_url") @db.VarChar(255)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// リレーション
posts Post[] @relation("UserPosts")
likes Like[] @relation("UserLikes")
followers Follow[] @relation("UserFollowers")
following Follow[] @relation("UserFollowing")
@@map("users")
}
// 例: 投稿モデル
model Post {
id String @id @default(uuid()) @db.Uuid
content String @db.Text
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// リレーション
userId String @map("user_id") @db.Uuid
user User @relation("UserPosts", fields: [userId], references: [id], onDelete: Cascade)
parentId String? @map("parent_id") @db.Uuid
parent Post? @relation("PostReplies", fields: [parentId], references: [id], onDelete: Cascade)
replies Post[] @relation("PostReplies")
likes Like[] @relation("PostLikes")
@@index([userId])
@@index([parentId])
@@index([createdAt])
@@map("posts")
}
・・・以下略・・・
ステップ7: Supabaseクライアントを設定
lib/supabase.tsを作成
import { createClient } from "@supabase/supabase-js";
import { createBrowserClient } from "@supabase/ssr";
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
// サーバーサイド用のSupabaseクライアント
export const supabaseServer = createClient(supabaseUrl, supabaseAnonKey);
// クライアントサイド用のSupabaseクライアント(ブラウザ専用)
export function createSupabaseClient() {
return createBrowserClient(supabaseUrl, supabaseAnonKey);
}
ステップ8: Prismaクライアントを設定
lib/prisma.tsを作成
// Prisma 7からアダプターが必要になった。
// インストールしたパッケージ
// @prisma/adapter-pg - PostgreSQLアダプター
// @types/pg - TypeScript型定義
import { PrismaClient } from "@prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
// Prisma 7では、アダプターが必須
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
ステップ8: prisma.config.tsファイルを作成
prismaのバージョンが7になって以降、schema.prismaやpackage.jsonに散らばっていた設定が、prisma.config.tsという単一の設定ファイルに集約されるようになった。
プロジェクトルートに**prisma.config.ts**を作成する。
// prisma.config.ts
import "dotenv/config";
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
// マイグレーション用は直接接続を使用(poolerではなくポート5432)
url: process.env["DIRECT_URL"] || process.env["DATABASE_URL"],
},
});
ステップ9: package.jsonにスクリプトを追加
package.jsonに以下のスクリプトを追加:
{
"scripts": {
"dev": "next dev",
"build": "prisma generate && prisma migrate deploy && next build",
"start": "next start",
"lint": "next lint",
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:studio": "prisma studio"
}
}
ステップ10: データベースマイグレーション
10-1. 接続テスト
まず接続できるか確認:プロジェクトルートにtest-connection.jsを作成
// test-connection.js
const { Client } = require('pg');
require('dotenv').config();
const client = new Client({
connectionString: process.env.DIRECT_URL,
});
console.log('データベース接続テスト中...');
client.connect()
.then(() => {
console.log('✅ 接続成功!');
return client.query('SELECT version()');
})
.then(result => {
console.log('PostgreSQL:', result.rows[0].version);
client.end();
console.log('\n✅ 次のステップ: npm run db:push');
})
.catch(err => {
console.error('❌ 接続失敗:', err.message);
process.exit(1);
});
コマンド
node test-connection.js
出力>
データベース接続テスト中...
✅ 接続成功!
PostgreSQL: PostgreSQL 17.6 on aarch64-unknown-linux-gnu, compiled by gcc (GCC) 13.2.0, 64-bit
10-2. マイグレーション実行
接続テストが成功したら:
Prismaクライアントを生成
npm run db:generate
初回マイグレーション
npm run db:migrate
※ マイグレーション名を聞かれたら「init」などと入力
prismaフォルダの下に"migration"フォルダが作成される。
または、開発中であればdb:pushでも可
npm run db:push`
これでSupabaseにテーブルができる。
ステップ11: 動作確認
簡単なAPIルートでテスト
app/api/test/route.tsを作成:
// app/api/test/route.ts
import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
export async function GET() {
try {
// ユーザー数を取得
const userCount = await prisma.user.count()
return NextResponse.json({
success: true,
userCount,
message: 'Database connected!'
})
} catch (error) {
console.error('Database error:', error)
return NextResponse.json(
{ success: false, error: 'Database connection failed' },
{ status: 500 }
)
}
}
ブラウザで http://localhost:3000/api/test にアクセスして確認。
出力>
{
success: true,
userCount: 0,
message: "Database connected!"
}
以上。