0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Tips】Cloud Run に Next.js アプリをデプロイしたら OpenAI の Project API Key が 401 になった話と解決法

0
Posted at

はじめに

ローカルでは問題なく動いていたNext.jsアプリを、Google CloudのCloud Runにデプロイしたところ、作成したアプリ内で実装していたOpenAIのAPI呼び出しだけが 401 Incorrect API key provided になってしまうという問題に遭遇しました。

最終的には

--set-build-env-vars--set-env-vars を両方に指定する

というシンプルな解決策で動きましたが、ここに至るまでの試行錯誤がなかなか大変だったので、備忘録としてまとめます。


デプロイするアプリについて

今回 Cloud Run にデプロイしたアプリは、アプリ上でサービスの名前を入れて、競合をChatGPTを用いて探すというシンプルなものです。
また、構成は以下の通りです:

.env.local
.gitignore
.next/ (ビルド成果物:ローカル専用)
next-env.d.ts
next.config.js
node_modules/ (ローカル専用)
package-lock.json
package.json
postcss.config.js
README.md
src/ (アプリ本体)
tailwind.config.js
tsconfig.json

前提条件

  • まずローカルにて npm run dev で動作確認済み
  • ローカルにて、本番ビルド確認として npm run build && npm startで動作確認済み
  • .env.local には OPENAI_API_KEY=sk-proj-... を設定

Cloud Runとは?

Cloud Run は、Google Cloud が提供する サーバーレスなコンテナ実行環境 です。
ソースコードをアップロードするだけで、アプリをコンテナ化して自動的に公開できます。

主な特徴

  • サーバー管理不要:インフラ構築や設定なしでデプロイ可能
  • 自動スケーリング:アクセス量に応じて自動で起動・停止
  • どんな言語でも対応:Dockerコンテナ化できるものであれば動作可能
  • HTTPリクエスト駆動:リクエストが来たときだけ起動する

動作の流れ

  1. ソースコードを Cloud Run にデプロイ
  2. 内部でビルド → コンテナ化
  3. コンテナが起動して公開URLが発行される

Cloud Run へのデプロイ手順

ローカルで動作確認したアプリを、下記の手順でCloud Run にデプロイしました。

① ソースを準備

以下のファイルを残し、node_modules/.next/ は削除してZIP化します。

.env.local
package.json
package-lock.json
next.config.js
tsconfig.json
tailwind.config.js
src/ などアプリ本体

② Cloud Shell でアップロード&解凍

Cloud Shell の上部にある「⋮」から ファイルをアップロード を選び、 Mac で動いたソースを ZIP にして丸ごとアップロードします

unzip myapp.zip
cd myapp

③ Cloud Run にデプロイ

gcloud run deploy my-next-app \
  --source . \
  --region=asia-northeast1 \
  --allow-unauthenticated

④ 環境変数を設定

gcloud run services update my-next-app \
  --region=asia-northeast1 \
  --update-env-vars VAR1=value1,VAR2=value2

数分でビルドが終わり、発行されたURL(https://xxx.a.run.app)にアクセスするとアプリが表示されます。


最初に遭遇したエラー

Cloud Run にアップロードしてビルドは通ったものの、API を叩くと以下のエラーに。

401 Incorrect API key provided: sk-proj-***********************************PBXj. You can find your API key at https://platform.openai.com/account/api-keys.

ローカルでは動くのに Cloud Run では失敗する

  • ローカル: .env.localOPENAI_API_KEY=sk-proj-... → OK
  • Cloud Run: OPENAI_API_KEY を環境変数に設定 → 401エラー

という状況でした。


試してダメだったこと

  • Cloud Run の「環境変数」に OPENAI_API_KEY を設定
  • デプロイ時に --set-env-vars OPENAI_API_KEY=... を指定
  • .env.local をそのままアップロード

どれも、ビルドは成功するのに実行時に 401 になりました。


なぜ失敗していたのか

  • Cloud Run は ビルド環境(Cloud Build)実行環境(Cloud Run) の2段階構成
  • .env.local はローカル開発専用で、Cloud Build では無視される
  • --set-env-vars実行時 用で、ビルド時には適用されない
  • Cloud Runは環境変数を ビルド時に焼き込む ので、ビルド時に空だと、そのまま空のキーが固定される

つまり

ビルド時に APIキー が空 → 空のままビルドされる → 実行時にキーがあっても無視される

ということのようでした。


解決した方法

ビルド時(Cloud Build)と実行時(Cloud Run)の両方に同じ API キーを指定することで解決しました。

gcloud run deploy insightlab-cloud \
  --source . \
  --region=asia-northeast1 \
  --allow-unauthenticated \
  --set-build-env-vars OPENAI_API_KEY=sk-proj-******LAIkA \
  --set-env-vars      OPENAI_API_KEY=sk-proj-******LAIkA

--set-build-env-vars: Cloud Build(ビルド時)に渡す
--set-env-vars: Cloud Run(実行時)に渡す


デプロイ後、APIを保護するためにSecret Managerに変数を移動

上記のままだと、APIキーがCloud Runの環境変数にそのまま格納されています。
よりセキュリティを担保するために、デプロイ後にSecret Managerに環境変数を追加し、Cloud Runはそこに格納されているAPIキーを参照するように修正しました。

【現状】

  • Cloud Run > デプロイしたサービス > リビジョン > コンテナ > 環境変数を確認すると、APIキーがそのまま格納されている

手順①

  • Secret Managerを選択し、「シークレットを作成」から新しいシークレットを作成し、APIキーを格納する

手順②

  • Cloud Run > デプロイしたサービス > 「新しいリビジョンの編集とデプロイ」を選択
  • コンテナ > 変数とシークレット > 環境変数として公開されるシークレットから、SecretManagerで追加したシークレットを指定する
    ※この時、「名前」はソース内で参照される名前にする

まとめ

  • sk-proj-... のような OpenAI の Project API Key を使うときは、ビルド時と実行時の両方に設定が必要
  • ローカルで動くのに Cloud Run で 401 になるときは、環境変数の食い違いを疑う
  • .env.local はアップロードしても無視される
  • セキュリティのため最終的には Secret Manager を使うと安心
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?