
Next.jsアプリケーションのVercel + Supabase + Prisma構成における本番環境と開発環境での環境構築ガイド
はじめに
普段の個人開発ではNext.jsを用いてアプリケーションを作成することが多く、以下の構成を頻繁に使用しています。
フロントエンド/バックエンド:Next.js
ホスティング:Vercel
データベース:Supabase (PostgreSQL)
ORM:Prisma
毎回この構成で環境構築する際に都度調べながら実装しているので、そろそろしっかりと体系的にブログにしておこうと思います。
今回作成するアーキテクチャの構成図は以下のようなものです。
本番環境ではVercelサーバーにアプリケーションをデプロイし、本番環境のSupabaseに接続します。
開発環境(ローカル環境)では、コンテナ上でローカルのSupabase DBを立ち上げてそちらに接続するようにします。
こうすることで互いの環境が干渉することなくアプリケーション開発に集中することが可能です。
以下の手順で環境構築を行なっていきたいと思います。
- Next.jsプロジェクト作成
- 本番環境Supabase作成
- Prismaセットアップ
- 開発環境(ローカル)Supabase作成
- Vercelサーバーへのデプロイ
使用PCはMacです。
1. Next.jsプロジェクト作成
まずは開発環境(ローカル)でNext.jsプロジェクトを作成します。
create-next-app
コマンドを使用して、Next.jsの雛形を作成します。
npx create-next-app@latest
プロンプトに回答して、Next.jsプロジェクトを起動してください。自分は今回「test-next-app」という名前でプロジェクトを作成しました。
完了したら、プロジェクト配下に移動して開発環境を起動してみます。
cd test-next-app
npm run dev
> test-next-app@0.1.0 dev
> next dev --turbopack
▲ Next.js 15.1.7 (Turbopack)
- Local: http://localhost:3000
- Network: http://192.168.10.102:3000
✓ Starting...
✓ Ready in 703ms
http://localhost:3000
にアクセスし、ローカルサーバーが立ち上がっていることが確認できれば完了です。
2. 本番環境Supabase作成
次に、Supabaseにて本プロジェクトの本番環境DBを作成していきます。
以下リンクにアクセスし、 「Start your project」 を選択してください。サインアップが完了していない場合は先にサインアップをしてください。
Organization(組織)がまだない場合は、先に作成します。
プロジェクトを作成する際、画像の赤線で囲ってある Database Passwordを設定し、必ず控えておいてください。 のちの設定で使用します。
また、Regionは「Northeast Asia (Tokyo)」にしておきます。
「Create new project」 を押してプロジェクト作成を完了します。
これにてDBの用意は完了です。とても簡単ですね。
この時点ではまだTable Editorを見てもなにもテーブルがないことが確認できます。
3. Prismaセットアップ
公式ドキュメントに従いPrismaのセットアップを行います。
Prismaインストール
Prisma CLIをインストールします
npm install prisma --save-dev
Prismaセットアップ
init
コマンドを実行してprisma/schema.prisma
を自動生成します。今回はデフォルトのpostgreSQLを使用するので、特にオプションは指定しません。
npx prisma init
実行結果
npx prisma init
✔ Your Prisma schema was created at prisma/schema.prisma
You can now open it in your favorite editor.
warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.
Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb.
3. Run prisma db pull to turn your database schema into a Prisma schema.
4. Run prisma generate to generate the Prisma Client. You can then start querying your database.
5. Tip: Explore how you can extend the ORM with scalable connection pooling, global caching, and real-time database events. Read: https://pris.ly/cli/beyond-orm
More information in our documentation:
https://pris.ly/d/getting-started
以下のようなファイルがprisma/schema.prisma
に生成されます。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
DBモデル定義
DBテーブルの定義をこのschemaファイルには記述します。公式ドキュメントの例と全く同じものを貼り付ってみます。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
+model User {
+ id Int @id @default(autoincrement())
+ email String @unique
+ name String?
+ posts Post[]
+}
+model Post {
+ id Int @id @default(autoincrement())
+ title String
+ content String?
+ published Boolean @default(false)
+ author User @relation(fields: [authorId], references: [id])
+ authorId Int
+}
マイグレーション
次に、実際に上で作成したスキーマファイルを実行してテーブルを作成してみましょう。
ただ現時点では開発環境のDBを用意していないので、一旦本番環境で正しくテーブルが作成できるかを確認してみます。(後ほど開発環境を用意します)
先ほど作成したSupabaseプロジェクトを開きます。Connect タブから ORM の Prisma を選択します。
中身をそのまま.evn
にコピーして貼り付けます。
プロジェクト配下の.env
ファイルにこの値を貼り付けます。その際に、[YOUR-PASSWORD]となっているところを先ほど控えておいたご自身のDBパスワードに置き換えてください。
# Connect to Supabase via connection pooling with Supavisor.
DATABASE_URL="postgresql://postgres.xxxxxxxxxxxxxxxxxxxx:examplepassword@aws-0-ap-northeast-1.pooler.supabase.com:6543/postgres?pgbouncer=true"
# Direct connection to the database. Used for migrations.
DIRECT_URL="postgresql://postgres.xxxxxxxxxxxxxxxxxxxx:examplepassword@aws-0-ap-northeast-1.pooler.supabase.com:5432/postgres"
また、prisma/schema.prisma
もSupabase用に置き換えます。具体的には、directUrl
を追加するだけです。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
+ directUrl = env("DIRECT_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
このように設定することで、.env
で指定したSupabaseへのURLに対してPrismaがマイグレーションやSQLを実行してくれるようになります。
それでは実際に本番環境のDBに対してマイグレーションが実行できるかを試してみたいと思います。
以下のコマンドを実行してください。
npx prisma migrate dev --name init
実行結果
npx 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:5432"
Applying migration `20250226075956_init`
The following migration(s) have been created and applied from new schema changes:
migrations/
└─ 20250226075956_init/
└─ migration.sql
Your database is now in sync with your schema.
Running generate... (Use --skip-generate to skip the generators)
✔ Generated Prisma Client (v6.4.1) to ./node_modules/@prisma/client in 50ms
prisma/migrations
ディレクトリが作成され、SQLが生成されていることが確認できると思います。
また、SupabaseのTable Editorを見ると本番環境にprisma/schema.prisma
で定義したDBテーブルモデルが反映されていることもわかります。
また、自動で@prisma/client
がインストールされ、テーブルモデルの型を定義してくれるprisma generate
コマンドも同時に実行されます。
これにより、DBのマイグレーションが成功し、DB操作を型安全に実装できるようになりました。
接続確認
では、マイグレーションが完了したので実際にNext.jsからUserが作成できるかの接続確認をしてみたいと思います。
以下のコードを、app/page.tsx
にそのまま貼り付けてください。
import Form from "next/form";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export default function Home() {
// Server Action
async function createUser(formData: FormData) {
"use server";
const name = formData.get("name");
const email = formData.get("email");
try {
// ユーザー作成処理
await prisma.user.create({
data: {
name: name as string,
email: email as string,
},
});
console.log("ユーザー作成に成功しました");
} catch (error) {
console.error("ユーザー作成に失敗しました, " + error);
}
}
return (
<div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-md">
<Form action={createUser} className="space-y-4">
<div>
<label
htmlFor="name"
className="block text-sm font-medium text-gray-700"
>
名前
</label>
<input
type="text"
name="name"
id="name"
className="text-black mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>
<div>
<label
htmlFor="email"
className="block text-sm font-medium text-gray-700"
>
メールアドレス
</label>
<input
type="email"
name="email"
id="email"
className="text-black mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
/>
</div>
<button
type="submit"
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
ユーザーを作成
</button>
</Form>
</div>
);
}
この状態でローカルサーバーを起動してみます。npm run dev
これは、名前とメールアドレスを入力するフォームを用意して、Userテーブルにレコード作成のPOSTリクエストを送る処理を実装しています。実際に名前とメールアドレスを入力して送信し、本番環境のUserテーブルにレコードが追加されていることが確認できたら成功です。
これにて、ローカルの開発環境から本番環境のSupabaseへの連携の設定が完了しました。
次は開発環境のSupabaseを用意してそちらに接続できるようにしていきたいと思います。
4. 開発環境のSupabase作成
開発環境のSupabase DBサーバーをコンテナで起動する
公式が用意してくれているSupabase CLIを用いて簡単に開発環境のDBをコンテナ上に用意することができます。
コンテナを使用するため、Docker Desktopを事前にインストールしておく必要があります。用意できていない方はDockerのインストールをしてください。自分は代替サービスとしてRancher Desktopを使用していますが、特に操作に変わりはありません。
準備ができたら、公式ドキュメントに従いSupabaseの開発環境を構築していきます。
自分はMacを使用しているのでbrewでインストールします。
brew install supabase/tap/supabase
インストールが完了したら、supabase init
コマンドを使用してセットアップを行います。
supabase init
Generate VS Code settings for Deno? [y/N] N
Generate IntelliJ Settings for Deno? [y/N] N
Finished supabase init.
エディタの設定は行わないため、プロンプトには「N」 を入力しましたが、自身の環境に合わせて変更してください。
完了すると、supabase
ディレクトリが作成され、諸々設定ファイルなどが追加されます。
最後に、supabase start
コマンドを使用してコンテナを起動します。少々時間がかかるかと思います。
supabase start
起動が完了すると以下のようなログが表示されます。
Started supabase local development setup.
API URL: http://127.0.0.1:54321
GraphQL URL: http://127.0.0.1:54321/graphql/v1
S3 Storage URL: http://127.0.0.1:54321/storage/v1/s3
DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
Studio URL: http://127.0.0.1:54323
Inbucket URL: http://127.0.0.1:54324
JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
S3 Access Key: 625729a08b95bf1b7ff351a663f3a23c
S3 Secret Key: 850181e4652dd023b7a98c58ae0d2d34bd487ee0cc3254aed6eda37307425907
S3 Region: local
この中から、以下のURLにアクセスしてください。
Studio URL: http://127.0.0.1:54323
すると、ローカル環境でSupabaseが立ち上がっていることが確認できると思います。
コンテナを停止したい場合は、supabase stop
コマンドを実行してください。
開発環境のSupabaseに接続する
現状だとまだ開発環境のDBにテーブルなどは特に作成されていないので、これから先ほどのprisma/schema.prisma
ファイルで定義したDBモデルを反映させていきたいと思います。
そのためには、先ほど本番環境に接続する際に設定した.env
ファイルを修正し、DATABASE_URL
とDIRECT_URL
をローカルのものと置き換えます。先ほどのログの中から、 DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
を確認してこちらに置き換えます。
# Connect to Supabase via connection pooling with Supavisor.
- DATABASE_URL="postgresql://postgres.xxxxxxxxxxxxxxxxxxxx:examplepassword@aws-0-ap-northeast-1.pooler.supabase.com:6543/postgres?pgbouncer=true"
+ DATABASE_URL="postgresql://postgres:postgres@127.0.0.1:54322/postgres"
# Direct connection to the database. Used for migrations.
- DIRECT_URL="postgresql://postgres.xxxxxxxxxxxxxxxxxxxx:examplepassword@aws-0-ap-northeast-1.pooler.supabase.com:5432/postgres"
+ DIRECT_URL="postgresql://postgres:postgres@127.0.0.1:54322/postgres"
これにより、DBの接続先が本番環境から開発環境(ローカル)に変更されます。
この状態で、マイグレーションコマンドを実行します。
npx prisma migrate dev
これにより開発環境のSupabase上に同じようにテーブルが作成されます。
さらにこの状態で、先ほどのUserフォームから名前とメールアドレスを送信すると、開発環境のSupabaseにUserレコードが作成されることが確認できたら開発環境の作成の成功です。
5. Vercelサーバーへのデプロイ
最後に、VercelへNext.jsアプリケーションをデプロイし、本番環境のアプリケーションからは本番環境へのSupabaseへ接続できるようにしたいと思います。
buildコマンドの修正
Vercelにデプロイする前に、buildコマンドを修正する必要があります。
Vercelでのビルド中にPrisma Clientの自動生成をトリガーさせるために、build
コマンドにprisma generate
も実行されるように追加してあげます。また、DBスキーマに変更があった際にそれを本番環境にも反映させる必要があるため、prisma migrate deploy
コマンドも追加してあげます。
"scripts": {
"dev": "next dev --turbopack",
- "build": "next build",
+ "build": "prisma generate && next build",
"start": "next start",
"lint": "next lint"
}
Vercelデプロイ
リポジトリをVercelサーバーへデプロイします。
サインアップがまだの場合は、先にサインアップを完了させてください。
サインアップが完了したら、Vercelにサインインしてプロジェクトを作成します。
どのGithubリポジトリをimportしてデプロイするかを問われるので、作成したアプリを選択します。
また、その際設定で環境変数を設定できるので、本番環境のDBへのDATABASE_URL
とDIRECT_URL
を設定しておきます。
`DATABASE_URL`と`DIRECT_URL`の取得方法
先ほど解説したように、これら本番環境のDBへのDATABASE_URL
とDIRECT_URL
はSupabaseのConnectタブから確認できます。[YOUR-PASSWORD]のところを本番環境のPasswordに置き換え変えることを忘れないでください。
デプロイが完了したら本番環境のサイトにアクセスすることが可能です。
接続確認
本番環境のドメインにアクセスし、以下の画面が表示されたら成功です。また、名前とメールアドレスを入力して本番環境のSupabaseに接続されるかを確認してみます。
無事Userレコードが作成されているのがわかります!(スキーマ上、同一のemailでは作成できないので注意)
これにて、以下の画像の構成のように、開発環境ではコンテナ上のローカルSupabaseに接続し、本番環境では本番Supabaseへ接続できるような構成が完成しました。
おわりに
今回はNext.jsアプリケーションをVercel + Supabase + Prismaの構成での本番環境と開発環境(ローカル)の環境構築をする方法を解説しました。
色々なドキュメントを横断して構築する必要があったので一つのブログにまとめてみました。
慣れてしまえば1時間ほどでサクッと環境構築ができ、高速な開発体験を得ることができるので今後もこの構成で個人開発などをしていきたいと思います。
以上、どなたかの参考になれば幸いです。
参考