はじめに
今回、React+Express+MongoDBを利用したTodoリストアプリをVercelにデプロイしました。
その際、バックエンドのデプロイでいくつかハマりポイントがあったので、備忘録として記事にまとめます。
使用技術
- 言語:TypeScript
- フロントエンド:React
- バックエンド:Express
- データベース:MongoDB (MongoDB Atlas)
- デプロイ先:Vercel
問題発生
Vercelにバックエンドをデプロイした際、発行されたURLにアクセスすると下記のようなエラーに遭遇しました。(デプロイ時の構成を触って何度かデプロイした際に遭遇したエラー)
404 NOT_FOUND
FUNCTION_INVOCATION_FAILED
-
405 Method Not Allowed
← これはPostmanからのリクエストテスト時のレスポンスで確認
これらのエラーに対して、ローカル環境では正常に動作していたため、デプロイ先での設定や構成に問題があると考え、原因として考えられるものをとりあえず確認し、ネットで情報を集めつつトライアンドエラーで対応していきました。
原因1: CORSの設定
まず、CORSの設定を見直しました。
Vercelのデプロイ環境ではCORS設定が重要になります。
ExpressでのCORS設定は以下のようにしました。
import cors from 'cors';
app.use(cors({
origin: true,
method: []
}));
この設定で、origin: true にすることでどのドメインからのリクエストでも受け入れられるようにしました。
※最終的にoriginはフロントエンドのURLを指定しました。
原因2: VercelのFunctions設定
Vercelでは、Expressのルーティングをサーバーレス関数として動作させるため、設定に注意が必要です。
特にファイルの構造やエントリーポイントを適切に設定する必要があります。
プロジェクトの構成(一部のみ抜粋、全容は→https://github.com/noritakaichinose/TodoList)
.
├── dist/
│ └── index.js
├── src/
│ ├── routes/
│ └── index.ts
└── vercel.json
TypeScriptで記述していたため、デプロイ時に適用されるvercel.json上でエントリーポイントを下記のように指定してやる必要がありました。
vercel.jsonの設定
{
"version": 2,
"builds": [
{
"src": "dist/index.js",
"use": "@vercel/node",
"config": { "includeFiles": ["dist/**"] }
}
],
"routes": [
{
"src": "/(.*)",
"dest": "dist/index.js",
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
"headers": {
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,OPTIONS,PATCH,DELETE,POST,PUT",
"Access-Control-Allow-Headers": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
}
}
]
}
原因3: MongoDBとの接続
バックエンドがVercelのサーバーレス環境で動作するため、MongoDB Atlasと接続する際に注意が必要です。
ローカルでは問題なく接続できていたのに、デプロイ環境ではエラーが発生していました。
問題点は下記です。
- Vercelのプロジェクト上での環境変数の設定
- MongoDBのネットワークアクセスの設定 (IPアドレスのホワイトリスト)
Vercelでの環境変数の設定
ローカルでは.envから環境変数として取得していたMongoDBの接続情報ですが、Vercel上でも環境変数を定義してやる必要があります。
プロジェクトダッシュボードから「Settings」タブを開き、「Environment Variables」の項目からKeyとValueの組み合わせで環境変数を追加することができます。
.envのインポートでも追加することができるので、どちらの方法でも結構です。
MongoDBのネットワークアクセスの設定
この問題はデプロイ時の構成、環境変数の問題が解決した後に気づいた問題ですが、MongoDBのホワイトリストの設定をしていないため、データベースへのアクセスができない状態になっていました。
ただ、VercelでデプロイされたアプリはIPアドレスが動的なので、結果的にすべてのIPアドレスを許可する「0.0.0.0/0」を設定することになりました。
まとめ
最終的に、自分の場合はVercelのFunctions設定とMongoDBのネットワークアクセスの設定が原因でした。
原因として挙げた箇所はチェックする価値があると思いますので、同様の問題に遭遇した場合は一度見直してみてください。