🛠️

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 の接続プーリングを利用するため、urldirectUrl の両方を設定します。

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.prismaoutput 指定を削除し、require('@prisma/client') もしくは作成した lib/prisma.js を経由するように統一することで解消しました。

まとめ

Express Generator の構成でも、少しの手順で Vercel / Prisma / Neon の 環境でアプリケーションを公開できました!

Discussion