[Google AI Pro プラン目線] Antigravity と Google Cloud — アプリを書いて GCP にデプロイ(第2回・アプリを書く)
📝 記事について: 第1回では Google Cloud SDK(gcloud)を用意して、簡単な使い方までやりました。第2回の今回は、Cloud Run に送るデータの準備です。Cloud Run へローカル SDK(gcloud)でアップするには、ソースと依存(requirements.txt など)があれば Buildpack でデプロイできるのですが、せっかくなので Docker も使ってみよう、という流れで Dockerfile まで触れています。筆者にとって Docker は初めてで、内容も多岐にわたるのでおぼつきませんが、必要最低限になるようかみ砕いてまとめたつもりです。利用する製品・サービスについては公開情報を参照しています。正確な内容は公式やデータソースをご確認ください。
この回では、Cloud Run に置くデータを用意します。
その内容は、デプロイ先(Cloud Run)がコンテナを組み立てるために必要な3種類のファイル(main.py・requirements.txt・Dockerfile)をそろえた、2本のアプリ(cloudrun_hello と cloudrun_ask)です。
この回ではそれらを Antigravity で開き、必要ならローカルで動かして確認するところまで進め、実際のデプロイは第3回で行います。
少し前から Cloud Run を使っていて、これまではローカルでコードを書き、Google Cloud の Cloud Run の Web 画面に貼り付けて実行し、エラーなら修正してまた実行、というやり方でした。
このシリーズの目的は、その一連の流れを Antigravity の中だけでできるようにすることです。

Web でやっていることをローカルでやる
Cloud Run では、Web コンソールの「サービスの作成」で次のどちらかを選んでデプロイします(公式:コンテナイメージのデプロイ)。
既存のコンテナイメージから1つのリビジョンをデプロイする(Artifact Registry や Docker Hub のイメージ URL を指定)、またはソース リポジトリから新しいリビジョンを継続的にデプロイする(リポジトリのソースからビルド)。いずれにしても、Cloud Run が動かすのは「コンテナ」です。
これまで、ローカルで書いたコードを Web の画面に貼り付けて実行し、エラーなら直してまた実行、というやり方をしていた方もいると思います。
本シリーズでは、その「Web でやる操作」をローカル(Antigravity)で完結させることを目指します。ソースと Dockerfile を手元で用意し、ローカルで確認してから、第3回で gcloud でデプロイする形です。

Cloud Run に必要なこと
Cloud Run は「コンテナ」の上でアプリを動かします。コンテナは、アプリとその実行に必要な環境(Python やライブラリなど)をひとまとめにした箱のようなものです。Cloud Run はこの箱を起動し、HTTP のリクエストをそこに送ります。
箱の作り方は Dockerfile に書きます。土台にするイメージ、入れるパッケージ、コピーするファイル、起動コマンドを指定するだけです。また、箱は「どの番号の入り口で待つか」を Cloud Run が PORT という環境変数で渡すので、アプリはその番号で HTTP を待つように書きます(コンテナ契約)。
必要なファイルは3つです。main.py(アプリ本体)、requirements.txt(pip で入れるパッケージ一覧)、Dockerfile(コンテナのビルド手順)。この3つをそろえれば、Cloud Run がコンテナを組み立てて動かせます(公式:ソースをコンテナにビルド)。API キーなどはデプロイ時に環境変数や Secret で渡せます(第3回で扱います)。
ソースと requirements.txt だけ(Dockerfile なし)でもデプロイできる:
gcloud run deploy サービス名 --source . で、Dockerfile がなくてもデプロイ可能。Buildpack が言語を検出し、requirements.txt から依存を読んでコンテナを組み立てます。ソースコードからサービスをデプロイする参照。本シリーズは「Dockerfile あり」で進めます。
Dockerfile の内容(1行ずつ)
cloudrun_hello と cloudrun_ask の Dockerfile は同じ構成です。コンテナの「土台 → 依存インストール → アプリ配置 → 起動方法」を順に書いています。行ごとの意味は次のとおりです。
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
ENV PORT=8080
EXPOSE 8080
CMD exec uvicorn main:app --host 0.0.0.0 --port ${PORT}
- FROM python:3.12-slim … 土台にするイメージ。Python 3.12 が入った軽量版の公式イメージです。ここからコンテナの「1枚目」が始まります。
- WORKDIR /app … このあとの作業場所を
/appにします。ファイルのコピーやコマンドはここを基準に行われます。 - COPY requirements.txt . … ホストの
requirements.txtをコンテナ内の/app(.)にコピーします。次のRUN pip installで使います。 - RUN pip install --no-cache-dir -r requirements.txt … コンテナを組み立てる段階で、
requirements.txtに書かれたパッケージ(FastAPI や uvicorn など)を pip でインストールします。--no-cache-dirはキャッシュを残さず、イメージを小さくするためです。 - COPY main.py . … アプリのソース
main.pyをコンテナの/appにコピーします。 - ENV PORT=8080 … 環境変数
PORTに 8080 を設定します。Cloud Run は起動時にPORTを渡すので、ここは「デフォルト値」です。Cloud Run 上では渡された番号が使われます。 - EXPOSE 8080 … このコンテナが 8080 番ポートで待ち受けることを宣言します。実際にリッスンするのは次の
CMDの uvicorn です。 - CMD exec uvicorn main:app --host 0.0.0.0 --port ${PORT} … 起動時に実行するコマンド。uvicorn で FastAPI を起動し、
${PORT}(Cloud Run が渡す番号)で HTTP を待つ。コンテナ契約に対応する部分。
ビルド時には FROM から COPY main.py までが実行されてイメージができ、実行時には CMD が動きます。main.py や requirements.txt を変えたら、イメージをやり直す(再ビルド)必要があります。
ランタイムのバージョン:コンテナでデプロイするとき、Cloud Run 上で動く Python はDockerfile の FROMで決まる。この Dockerfile は python:3.12-slim なので、Cloud Run 上も Python 3.12。
「Cloud Run の最新が 3.14」は Buildpack など Google がランタイムを渡す場合の話。Dockerfile でデプロイするときは FROM のバージョンがそのまま使われる。ローカル(例: 3.13)とデプロイ先(3.12)が違っても問題ない。
ランタイム・タグの確認場所:Web で選ぶ「ランタイム」(Python 3.12 など)→ 公式「サポートされている言語ランタイムとベースイメージ」の表。Dockerfile の FROM に書くタグ(例: 3.12-slim)→ Docker Hub の Python 公式イメージの「Tags」一覧。
-slim:ランタイム名ではなく、Docker 公式イメージの「バリアント」(軽量版)の一つ。Web の「ランタイム」はバージョンのみなので「slim」は出てこない。Dockerfile でベースを指定するときだけ 3.12-slim などと書く。揃えたい場合は FROM を python:3.13-slim などに変更。
用意する2本
cloudrun_hello:/・/health・/version を返す Hello World。
cloudrun_ask:GET /ask?q=質問 で Gemini が短文で答える API(Google AI Studio で取得した API キーを環境変数 GEMINI_API_KEY で渡す)。
どちらも同じ構成で、各フォルダに main.py、requirements.txt、Dockerfile の3ファイルがあります。以下、クリックで開閉できます(デフォルトは閉じています)。
各アプリの3ファイル(クリックで開く・初期は閉じています)
cloudrun_hello
main.py
FastAPI で /(HTML)、/api、/health、/version を定義。フォルダ内のファイルを参照してください。
requirements.txt
fastapi>=0.100.0 uvicorn[standard]>=0.22.0
Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
ENV PORT=8080
EXPOSE 8080
CMD exec uvicorn main:app --host 0.0.0.0 --port ${PORT}cloudrun_ask
main.py
FastAPI で /(HTML)、/ask?q= で Gemini API を呼び出し。環境変数 GEMINI_API_KEY を使用。フォルダ内のファイルを参照してください。
requirements.txt
fastapi>=0.100.0 uvicorn[standard]>=0.22.0 google-generativeai>=0.8.0
Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
ENV PORT=8080
EXPOSE 8080
CMD exec uvicorn main:app --host 0.0.0.0 --port ${PORT}Step 1:フォルダを開く
cloudrun_hello と cloudrun_ask が入っているフォルダ(例:brief029)を Antigravity で開きます。まだ用意していない場合は、各フォルダに main.py・requirements.txt・Dockerfile を置いてください(サンプルは brief029 配下を参照)。
Step 2:ローカルで動かして確認する
どちらも、そのフォルダで pip install -r requirements.txt を実行したあと、uvicorn で起動し、ブラウザで表示を確認します。ローカルではポート 8000 を使います(Cloud Run では PORT を使用)。
cloudrun_hello
pip install -r requirements.txt
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
ブラウザで http://localhost:8000/ を開きます。
cloudrun_ask
同じターミナルで、先に GEMINI_API_KEY を設定してから起動します(PowerShell の例)。
pip install -r requirements.txt
$env:GEMINI_API_KEY="取得したAPIキー"
python -m uvicorn main:app --reload --host 0.0.0.0 --port 8000
ブラウザで http://localhost:8000/ask?q=こんにちは を開きます。終了は Ctrl+C。uvicorn が認識されない場合は python -m uvicorn ...、ポートが使えない場合は --port 8000 を付けてください。



おわりに
2本とも、Cloud Run 用の3ファイルがそろった状態で用意できました。第3回では、Antigravity のターミナルから gcloud でこれらを Cloud Run にデプロイする流れをまとめます。
Artist's Perspective
「くたびれた貧乏なおっさんがひたすら調べていると、Antigravity の情報収集能力、ほんとにすごいな……と思う。ただ、集まる情報量が半端なくて、ツールとツール、それに規格が絡むと説明が無駄に長くなるのはいつの時代も同じで、内容は多岐にわたり、文章は長い長い。目がしょぼしょぼ。それにしても Google Cloud の公式情報、もう巨大すぎて意味不明である。Google サイト内で、よくまあここまでの技術情報を書いたな、と笑いながら拝見している。」
データソース・参考リンク
本記事は以下の情報源を参考にしています。内容の正確性については、必ず元のデータソースをご確認ください。