

本番環境を一から構築してデプロイした際、開発環境では発生しなかった様々な問題に遭遇しました。この記事では、それぞれの問題の原因と解決策を記録します。
Prisma Postgres × pgvectorで新規DBデプロイ時に起きるエラーの対処法
NextAuth v5のCloudflare Workers環境でのUntrustedHostエラーの解決
Stripe環境変数未設定時のビルドエラーへの対処
robots.txt / noindexを環境変数で切り替える方法
Cloudflare Workers APIでカスタムドメインを設定する方法
DBから直接認証トークンを取得してE2Eテストを行う方法
Cloudflare Workers + Next.jsで本番デプロイを行う方
NextAuth v5をCloudflare Workers上で動かす方
CI/CDパイプラインのデプロイエラーに対処する方
GitHub Actionsのデプロイで prisma db push が失敗。
Error: ERROR: type "vector" does not exist
新規作成したPrisma PostgresのDBにpgvector拡張がインストールされていない。開発環境ではDockerの初期化スクリプトで自動インストールされていたため気づかなかった。
DIRECT_URL を使ってローカルからpgvector拡張をインストール。
psql '[DIRECT_URL]' -c 'CREATE EXTENSION IF NOT EXISTS vector;'
新規DBを作成した際は、マイグレーション前にpgvector等の拡張をインストールする手順をチェックリストに入れておく。
pgvector解決後も prisma db push が失敗。
Error: Use the --accept-data-loss flag to ignore the data loss warnings
新規の空DBにスキーマをpushする際、unique制約の追加などが「データ消失の可能性がある変更」として検出される。
初回のみローカルから手動実行。CIのコマンドはそのまま維持。
DIRECT_URL='[接続文字列]' bunx prisma db push --accept-data-loss
--accept-data-loss をCIに常設するのは危険。運用中にスキーマ変更した際、データが消える可能性がある。初回セットアップ時のみ手動で実行するのが安全。
OpenNextビルドが失敗。
Error: STRIPE_SECRET_KEY environment variable is not set
Stripeの初期化コードが起動時に環境変数を必須としてthrowしている。Stripe本番設定が完了していない段階でデプロイしたため発生。
ダミー値をGitHub Secretsに設定してビルドを通す。
gh secret set STRIPE_SECRET_KEY --env prod --body 'sk_test_dummy'
gh secret set STRIPE_PUBLISHABLE_KEY --env prod --body 'pk_test_dummy'
gh secret set STRIPE_WEBHOOK_SECRET --env prod --body 'whsec_dummy'
gh secret set STRIPE_PRICE_ID --env prod --body 'price_dummy'
環境変数が未設定でもアプリがクラッシュしないよう、Stripeの初期化にガード処理を入れる設計も検討すべき。
/api/auth/session が500エラーを返す。
wrangler tail でWorkerのログを確認。
npx wrangler tail [worker-name] --format json
ログに以下のエラー:
[auth][error] UntrustedHost: Host must be trusted. URL was: https://example.com/api/auth/session
NextAuth v5はCloudflare Workers環境ではリクエストヘッダの host の扱いが通常のNode.jsサーバーと異なる。NEXTAUTH_URL を設定していても trustHost が明示的に必要。
NextAuthの設定に trustHost: true を追加。
export const { handlers, signIn, signOut, auth } = NextAuth({
trustHost: true, // ← これを追加
adapter: PrismaAdapter(prisma),
session: { strategy: "jwt" },
// ...
});
Cloudflare Workers上でNextAuth v5を使う場合、trustHost: true は必須と考えた方がいい。
Cloudflare Dashboardに行かなくても、APIで設定可能。
curl -X PUT \
"https://api.cloudflare.com/client/v4/accounts/[ACCOUNT_ID]/workers/domains" \
-H "Authorization: Bearer [API_TOKEN]" \
-H "Content-Type: application/json" \
-d '{"hostname":"example.com","service":"worker-name","environment":"production"}'
SSL証明書は自動発行
DNSがCloudflareで管理されていれば即時反映
prod: 本来はSEO公開したいが、今はまだ非公開にしたい
dev: 常に非公開
同じコードベースで環境ごとに制御したい
環境変数 ROBOTS_ALLOW で切り替え。
robots.ts:
export default function robots(): MetadataRoute.Robots {
const isPublic = process.env.ROBOTS_ALLOW === "true";
if (!isPublic) {
return {
rules: [{ userAgent: "*", disallow: ["/"] }],
};
}
return {
rules: [{
userAgent: "*",
allow: "/",
disallow: ["/api/", "/admin/", "/mypage/", "/chat/", ...],
}],
sitemap: `${SITE_URL}/sitemap.xml`,
};
}
layout.tsx:
robots: {
index: process.env.ROBOTS_ALLOW === "true",
follow: process.env.ROBOTS_ALLOW === "true",
// ...
},
運用:
非公開(デフォルト): ROBOTS_ALLOW を設定しない
公開時: gh secret set ROBOTS_ALLOW --env prod --body "true" → 再デプロイ
メール認証フローのあるアプリで、PlaywrightによるE2Eテスト時にログインできない。
DBに直接ログイントークンを作成し、Playwrightでそのトークンを使ってログインする。
-- 有効期限10分のログイントークンを直接作成
INSERT INTO "VerificationToken" (identifier, token, expires)
VALUES ('login:[email protected]', 'e2e-test-token', NOW() + INTERVAL '10 minutes');
// Playwrightでトークンを使ってログイン
await page.goto('https://example.com/api/auth/verify-login?token=e2e-test-token');
await page.waitForURL('**/chat**');
メール送信を待つ必要がない
CI/CDでも自動テスト可能
トークンの有効期限を自由に設定できる
wrangler tail --format json でWorkerのログをリアルタイム確認できる。本番環境のデバッグに非常に便利-target オプションで依存関係のないリソースだけ先にapplyできる。例: terraform apply -target=module.r2pgvector: 新規DB作成後に CREATE EXTENSION IF NOT EXISTS vector; を忘れずに
prisma db push: 初回は --accept-data-loss が必要だが、CIには入れない
NextAuth v5 + Workers: trustHost: true は必須
Stripe未設定: ダミー値でビルドを通し、後から差し替え
robots.txt: 環境変数で公開/非公開を切り替え。コード変更不要
E2Eテスト: DB直接操作でメール認証をバイパス可能