📚

【Next.js】PrismaをつかったアプリをVercelにデプロイしてみる

2025/01/12に公開

Prisma を使った Next.js アプリケーションを Vercel にデプロイしてみます。

DB も Vercel のものを使用してデプロイに挑戦します!!

デプロイするアプリケーション

↓ の記事で作成したものをデプロイします。

https://zenn.dev/kuuki/articles/nextjs-use-prisma-postgresql-local/

GitHub リポジトリはこちら

https://github.com/hisuihisui/sample-prisma-next-app

想定読者

  • デプロイするアプリケーションの GitHub リポジトリがある。
  • Vercel のアカウントを持っている

Vercel で PostgreDB をセットアップ

https://vercel.com/dashboard/stores

こちらにアクセスして、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 をたたくとエラーになるので、いくつかコードを修正します

詳しくは ↓ をご覧ください

https://zenn.dev/kuuki/articles/nextjs-typeerror-fetch-failed-vercel/

・.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 に追記をします

詳細は ↓ をご覧ください

https://zenn.dev/kuuki/articles/vercel-nextjs-resolve-cors-error/

/**@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を書き換えます

https://github.com/prisma/deployment-example-vercel

下記のように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 へアプリケーションをデプロイ

https://zenn.dev/kuuki/articles/nextjs-vercel-deploy/

こちらの記事を参考に Vercel にアプリケーションをデプロイします

今回は、Environment Variables に DB の接続情報を設定してください

POSTGRES_PRISMA_URL と POSTGRES_URL_NON_POOLINGに先ほどメモした値を設定します

また、NEXT_PUBLIC_API_PREFIXに **https://**を設定します

動作確認

デプロイが完了したら、動作確認をします

アプリにアクセスして、ユーザー登録、一覧表示ができていれば OK です

参考記事

https://vercel.com/guides/nextjs-prisma-postgres

https://www.prisma.io/docs/guides/deployment/serverless/deploy-to-vercel

https://github.com/prisma/deployment-example-vercel

Discussion