🏃‍♂️

【初心者向け】コンテナイメージをCloud Runにデプロイする

に公開

はじめに

こんにちは。
以前の記事で作成したAPIはローカルで動かしていましたが、今回はそれをCloud Runにデプロイする方法についてまとめます。

https://zenn.dev/cvl/articles/001ca08d2c72c8

必要なリソース

  • Docker Desktop
  • Artifact Registry
  • Cloud Run
  • Secret Manager

コンテナイメージの作成

準備

まずは作成したmain.pyが配置されているディレクトリから説明します。
今までvenvにインストールしていた必要な依存関係はrequirements.txtに記載します。

API(main.py)自体への変更は不要です。

ディレクトリ
fastapi-app/
├─ main.py
├─ requirements.txt
├─ .env
└─ Dockerfile
requirements.txt
fastapi
uvicorn[standard]
pydantic
google-genai

もしローカルの環境変数を使っていた場合は.envファイルなどファイルを作って配置しましょう
環境変数はこの後のフェーズでSecret Managerを利用するよう変更するので削除して問題ないです。

.env
APIKEY=xxxxxxxxxxxxxxxxxxx

Dockerfileの作成

Dockerfileは一言でいうと、「実行環境(VM)のセットアップ手順を書いた定義書」 です。
サーバレスとはいえ、実際にOSがないとどのアプリも稼働しないので、OSの情報(今回はLinux)や依存関係(今回は上記requirements.txtに記載)のインストールを手順として定義したファイルをDockerfileと呼びます。

原則上からコマンドを実行していく形になるので、書き出しはFROMで環境を定義、以降はAPIの動作に必要な環境の準備を定義しています。

好奇心でRC版使ってますが普通に安定版使ってください。

Dockerfile
FROM python:3.14-rc-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

イメージ作成

プロジェクト直下で以下を実行します。

docker build は、Dockerイメージという「設計図(または金型)」を生成するコマンドです。

何をしているかというと、作成したDockerfileに書かれた命令(OSの種類、ソフトのインストール、ファイルのコピーなど)を上から順に実行し、実行可能なパッケージ(イメージ)に固めてくれています。

powershell
docker build -t fastapi-app .

一方で、docker run は、作成したイメージを元にして、実際に コンテナ(仮想的な実行環境)を起動するコマンドです。

docker build で作ったイメージを読み込み、メモリ上に独立したプロセスとして展開して、アプリケーションを動かします。
今回は変数ファイルを利用しているので --env-fileで呼び出しています。

powershell
docker run -p 8080:8080 --env-file .env fastapi-app

これで、ローカルからリクエストを投げれば応答が返ってきます。

Cloud Runへのデプロイ

Artifact Registoryの作成

まずは認証を通します。

gcloud
gcloud auth configure-docker asia-northeast1-docker.pkg.dev

ちなみに認証情報は以下に格納されます

C:\Users\<ユーザー名>\.docker\config.json

Dockerイメージのビルド/プッシュ

プロジェクトIDや名称はご自身の環境に合わせてください。

ビルド
docker build -t asia-northeast1-docker.pkg.dev/プロジェクトID/fastapi-repo/fastapi-app:latest .
プッシュ
docker push asia-northeast1-docker.pkg.dev/プロジェクトID/fastapi-repo/fastapi-app:latest

こんな感じ↓

Secret Managerの構築

環境変数を暗号化するためにSecret Managerを利用します。

echo -n "API_KEYの値" | `
gcloud secrets create GEMINI_API_KEY `
--data-file=-

注意:Cloud Runに紐づくサービスアカウントにSecret Managerを読み込む権限を付与してください。

Cloud Runの構築

コマンドで一発です。
運用回りの設定はコンソールからで大丈夫
検証用でCloud Runの環境変数に直接APIキーを格納することもできますが、Secret Managerを利用することを推奨します。

gcloud run deploy fastapi-app `
--image asia-northeast1-docker.pkg.dev/プロジェクトID/fastapi-repo/fastapi-app:latest `
--region asia-northeast1 ` 
--platform managed ` 
--set-secrets API_KEY=API_KEY:latest

以下でCloud Runの環境変数も利用できますが、--set-secretsfa の利用を推奨します。
--set-env-vars API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX

デプロイされたことはコンソールからも確認できます。

変数もSecret Managerを使っていることが分かります。

動作確認

動作確認をしてみます。
今回はCloud Runの設定でIAM/IAPで認証を通さないと利用できない設定にしているので、ローカルから動作確認をするためには一工夫必要です。

👉ID トークン(Authorization: Bearer)を付けてリクエストする必要がある

Google Cloud環境に接続したターミナル(Cloud Shellも可)から以下のコマンドを実行し、IDトークンを取得します。

gcloud auth print-identity-token

めっちゃ長いトークンが出てくるので控えます。

以下のようにリクエストヘッダにトークンを組み込むことで認証を通したうえで接続できるようになります。
パス等はご自身の環境に合わせてください。

REST
POST https://fastapi-app-xxxxxxxx.asia-northeast1.run.app/generate HTTP/1.1
Authorization: Bearer {ID_TOKEN}
Content-Type: application/json

{
  "prompt": "こんにちは"
}

gcloud auth print-identity-tokenコマンドで発行されるトークンの有効期限は1時間なので注意

まとめ

デフォルトの設定であれば割と簡単にデプロイすることができますね。
これからもいろいろ試していきます。

参考

https://docs.cloud.google.com/run/docs/deploying?hl=ja

Discussion