Express + Prisma + PostgreSQL を Vercel にデプロイする
概要
Expressで作成したプロジェクトを、Prisma と Neonを使って Vercel にデプロイする際にいくつかハマりどころがあったので、うまくいった手順をまとめました。
1. 技術スタック
- Framework: Express (Express Generator 構成)
- ORM: Prisma
- Database: PostgreSQL (Vercel Storage / Neon)
- Platform: Vercel
2. Vercel 用のディレクトリ構成
Vercel はサーバーレス関数として動作するため、通常の bin/www による常駐サーバー形式は利用できません。
以下のファイルを新規作成しました。
.
├── api/
│ └── index.js # Vercelのエントリーポイント
├── lib/
│ └── prisma.js # Prismaのシングルトン管理
├── prisma/
│ └── schema.prisma
├── vercel.json # ルーティング設定
├── app.js
└── package.json
3. 各ファイルの書き換え
vercel.json
すべてのリクエストを api/index.js に集約。
{
"rewrites": [{ "source": "/(.*)", "destination": "/api/index.js" }]
}
api/index.js
bin/www の代わりに、Vercel が Express を呼び出すための窓口。
const app = require('../app');
module.exports = app;
lib/prisma.js
リクエストのたびに DB 接続が増え続けるのを防ぐために、global オブジェクトを使って Prisma Client を使い回し。
const { PrismaClient } = require('@prisma/client');
const prisma = global.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') {
global.prisma = prisma;
}
module.exports = prisma;
4. Prisma の設定
schema.prisma
Neon の接続プーリングを利用するため、url と directUrl の両方を設定します。
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("POSTGRES_PRISMA_URL")
directUrl = env("POSTGRES_URL_NON_POOLING")
}
package.json
Vercel デプロイ時に自動で Prisma Client を生成させるため、postinstall に追記します。
"scripts": {
"postinstall": "prisma generate"
}
5. Neon の設定
1. Vercel Storage の作成
Vercel(https://vercel.com/ )ダッシュボードの「Storage」タブにて、「Create Database」を選択してデータベースを作成。データベースは「Neon」を選択。
2. 環境変数 の確認
作成が完了すると、データベースのページに遷移。画面中央の「.env.local」を控えて、ローカルの.envにコピー
3. マイグレーションの実行
ローカル環境にて、改めてマイグレーションを実施。
npx prisma migrate dev --name init
6. Vercelにデプロイ
1. Githubにプッシュ
作成したプロジェクトをGitHubにプッシュ。
2. Vercelにインポート
Vervcelダッシュボード「Overview」タブから、右上「Add New」より「Project」を選択。該当のGithubリポジトリをインポート。自動でデプロイさる。
3. Neonとの紐づけ
デプロイ後、「Storage」タブより、作成したNeonデータベースをConnectする。
7. 遭遇したトラブル
エラー:Cannot find module '../generated/prisma'
Prisma の output 先をカスタム設定している場合に発生しやすいです。schema.prisma の output 指定を削除し、require('@prisma/client') もしくは作成した lib/prisma.js を経由するように統一することで解消しました。
まとめ
Express Generator の構成でも、少しの手順で Vercel / Prisma / Neon の 環境でアプリケーションを公開できました!
Discussion