【Next.js】PrismaをつかったアプリをVercelにデプロイしてみる
Prisma を使った Next.js アプリケーションを Vercel にデプロイしてみます。
DB も Vercel のものを使用してデプロイに挑戦します!!
デプロイするアプリケーション
↓ の記事で作成したものをデプロイします。
GitHub リポジトリはこちら
想定読者
- デプロイするアプリケーションの GitHub リポジトリがある。
- Vercel のアカウントを持っている
Vercel で PostgreDB をセットアップ
こちらにアクセスして、DB を作成します
Postgres の Createをクリックします
ダイアログがでて来るので、Postgres が選択されていることを確認してContinueをクリック
(2023/09 現在)Postgre は Betaなので、↓ が表示されます
Beta 版でも大丈夫だよと思ったら、Acceptを押し進みます
DB の名前とリージョンを指定して、Createをクリックします
作成されると DB の詳細画面に遷移します
ここでDB への接続情報を確認できます
あとで使うので、接続情報をメモしておきます
必要なのは、Prismaと .env.localの 2 つの情報になります
機密情報は*(アスタリスク)で隠れていますが、Show Secretで見ることができます
・Prisma
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL") // uses connection pooling
directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
}
・.env.local
POSTGRES_URL="************"
POSTGRES_PRISMA_URL="************" // これが必要
POSTGRES_URL_NON_POOLING="************" // これが必要
POSTGRES_USER="************"
POSTGRES_HOST="************"
POSTGRES_PASSWORD="************"
POSTGRES_DATABASE="************"
これで Vercel に DB を作成できました
schema.prisma を修正
先ほど確認した Prisma の情報を schema.prisma に反映させます(datasource db を編集)
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL")
directUrl = env("POSTGRES_URL_NON_POOLING")
}
...
schema.prisma を変更したので Prisma Client を更新しないとローカル環境でアプリケーションが正しく動作しない可能性があります
こちらを実行して Prisma Client を更新してください
npx prisma generate
schema.prisma の編集によって読み込む環境変数名を変更した場合はenv ファイルの中身も変数名を変更してください!
コード修正
ビルドエラーの回避
そのままだとビルド時に API をたたくとエラーになるので、いくつかコードを修正します
詳しくは ↓ をご覧ください
・.env
NEXT_PUBLIC_API_PREFIX="http://"
NEXT_PUBLIC_VERCEL_URL="localhost:3000"
・src/lib/config.ts
export const config = {
apiPrefix: process.env.NEXT_PUBLIC_API_PREFIX ?? "http://",
apiHost: process.env.NEXT_PUBLIC_VERCEL_URL ?? "localhost:3000",
};
・src/components/addUser.tsx
...
export default function AddUser() {
...
const fetchAsyncAddUser = async () => {
...
// APIのURL
const url = config.apiPrefix + config.apiHost + "/api/user";
...
};
...
};
・src/components/userList.tsx
import { config } from "@/lib/config";
export default async function UserList() {
// APIのURL
const url = config.apiPrefix + config.apiHost + "/api/user";
// APIへリクエスト
const res = await fetch(url, {
cache: "no-store",
});
try {
// レスポンスボディを取り出す
const data = await res.json();
return (
<div>
<h2>All Users</h2>
{data.map((user: any, index: any) => (
<div key={index}>
<span>Name: {user.name}</span>
<span>Email: {user.email}</span>
<span>
Posts: {user.posts.map((value: any) => `${value.title},`)}
</span>
<span>Profile: {user.profile?.bio}</span>
</div>
))}
</div>
);
} catch {
return <div></div>;
}
}
CORS 対策
CORS エラー対策のために next.config.js に追記をします
詳細は ↓ をご覧ください
/**@type {import('next').NextConfig} */
const nextConfig = {
// 全ての API routes にマッチ
async headers() {
return [
{
// 対象APIのパスパターン
// 今回は src/app/api/ 配下にAPIを作っているので下記のようにする
source: "/api/:path*",
headers: [
{
// CORSを許可するオリジン
key: "Access-Control-Allow-Origin",
// すべてのオリジンを許可するなら * (アスタリスク)
// ただセキュリティ的にはよろしくないので注意
value: "https://<vercelのプロジェクト名>.vercel.app",
},
{
// 許可するメソッド
key: "Access-Control-Allow-Methods",
value: "GET,OPTIONS,POST",
},
{
// 許可するリクエストヘッダ
key: "Access-Control-Allow-Headers",
value: "Content-Type",
},
],
},
];
},
};
module.exports = nextConfig;
ビルドコマンドを修正
そのままのビルドコマンドだと Prisma 系の内容が DB に反映されないので、修正します
↓ のリポジトリを参考にpackage.jsonを書き換えます
下記のようにvercel-buildコマンドを追加しました
{
"name": "sample-prisma-next-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"vercel-build": "prisma generate && prisma migrate deploy && next build",
"lint": "next lint"
},
...
}
build よりもvercel-build の方が Vercel にビルドしたときに優先されるみたい。 ドキュメントは発見できませんでした。。。
Vercel へアプリケーションをデプロイ
こちらの記事を参考に Vercel にアプリケーションをデプロイします
今回は、Environment Variables に DB の接続情報を設定してください
POSTGRES_PRISMA_URL と POSTGRES_URL_NON_POOLINGに先ほどメモした値を設定します
また、NEXT_PUBLIC_API_PREFIXに **https://**を設定します
動作確認
デプロイが完了したら、動作確認をします
アプリにアクセスして、ユーザー登録、一覧表示ができていれば OK です
参考記事
Discussion