Skip to content

GitHub Actions でデプロイ

GitHub リポジトリと接続する 方法は、 push するだけで自動デプロイされて手軽だけど、 テストの自動実行を挟めない。pytest が通ったときだけデプロイしたい場合は、デプロイトークン(Deploy Token)を使って GitHub Actions から fastapi deploy を実行する。
cf. Deploy Tokens - FastAPI Cloud

FastAPI Cloud へのデプロイ方式の比較。

やりたいこと 方式 テスト
ローカル環境からデプロイ fastapi deploy コマンド デプロイ前に手動で別途実行
push したらデプロイ GitHub リポジトリと接続する push 前に手動で別途実行
テストが通ったときだけデプロイ GitHub Actions + デプロイトークン 自動実行が可能

デプロイトークン作成

CI からのデプロイに個人アカウントの認証情報は使わず、専用のデプロイトークンを作る。ダッシュボードのアプリ詳細で Tokens を開くと Deploy Tokens の画面になるので、 Create Token を押す。

FastAPI Cloud のアプリ詳細の Tokens。まだトークンがなく Create Token ボタンがある

Create Deploy Token のダイアログが開く。トークン名と有効期限(日数で指定、最大 365 でデフォルトは 90)を決めて Create Token を押す。

Create Deploy Token ダイアログ。トークン名と有効期限の日数を入れて Create Token を押す

トークンの値が表示される。見られるのはこのときだけなのでコピーしておく。

Token Created Successfully の画面。トークンの値はこの画面でしか見られないので、コピーしてから閉じる

一覧に戻ると、作ったトークンが Active として並んでる。一覧の下にヒントが出てる通り、この値は FASTAPI_CLOUD_TOKEN 環境変数として使う。コピーし損ねたときは、回転矢印のアイコンでトークンを作り直せる(古い値はその場で無効になる)。期限が切れると Expired と表示されて、そのままだとデプロイが失敗するようになる。期限が切れる前に作り直してローテーションしておく。

Deploy Tokens の一覧。作成したトークンが Active として並び、FASTAPI_CLOUD_TOKEN 環境変数で使う旨のヒントが出ている


GitHub Secrets に登録する

リポジトリの SettingsSecrets and variablesActions で、次の 2 つを登録する。登録のやり方は GitHub Actions の Secrets と同じ。

Secret 名
FASTAPI_CLOUD_TOKEN デプロイトークンの値
FASTAPI_CLOUD_APP_ID アプリの ID(UUID)。ダッシュボードのアプリ詳細で確認できる

GitHub リポジトリの Actions secrets and variables。Repository secrets に FASTAPI_CLOUD_APP_ID と FASTAPI_CLOUD_TOKEN が登録されている


ワークフローを書く

テストが通ったらデプロイするときのワークフロー例。

.github/workflows/ci-cd.yml
name: Test and deploy

on:
  push:
    branches: [ "main" ]

jobs:
  test-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v7

      - name: Install uv
        uses: astral-sh/setup-uv@v8.2.0
        with:
          enable-cache: true
          cache-dependency-glob: "uv.lock"

      - name: Install dependencies
        run: uv sync --frozen

      - name: Run tests
        run: uv run pytest -v

      - name: Deploy to FastAPI Cloud
        run: uv run fastapi deploy
        env:
          FASTAPI_CLOUD_TOKEN: ${{ secrets.FASTAPI_CLOUD_TOKEN }}
          FASTAPI_CLOUD_APP_ID: ${{ secrets.FASTAPI_CLOUD_APP_ID }}

checkout → uv のセットアップ → uv sync --frozen → pytest までは GitHub Actions のサンプルと同じ流れ。追加したのは最後の deploy ステップ。

  • uv run fastapi deploy … ローカルで打つのと同じコマンド。 CI のサーバーでは fastapi login してないので、 Secrets に登録した 2 つを環境変数で渡して認証する。 FASTAPI_CLOUD_APP_ID がデプロイ先アプリの指定になる(ローカルだと .fastapicloud/cloud.json に保存されてるリンク情報の代わり)。
  • ステップは上から順に実行されて、失敗したらそこで止まる。 pytest が落ちたら Deploy to FastAPI Cloud までたどり着かない。

ジョブを分けてもいい

ここでは 1 つのジョブ内のステップ順で「テスト → デプロイ」を保証してるけど、 GitHub Actions のサンプルみたいに testdeploy をジョブに分けて needs: test でつなぐ形でもいい。

テスト側に特別なことは何もいらなくて、いつもの pytest のテストがあればいい。例えばこんなアプリとテスト。

main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/inc")
def inc(x: int):
    return {"result": x + 1}
test_main.py
from fastapi.testclient import TestClient

from main import app

client = TestClient(app)


def test_inc_positive():
    response = client.get("/inc?x=5")
    assert response.status_code == 200
    assert response.json() == {"result": 6}


def test_inc_zero():
    response = client.get("/inc?x=0")
    assert response.status_code == 200
    assert response.json() == {"result": 1}


def test_inc_invalid_input():
    response = client.get("/inc?x=hello")
    assert response.status_code == 422

動作確認

main に push すると GitHub Actions が起動して、テストが通るとそのまま fastapi deploy まで進む。

Actions の実行結果。Run tests が通って Deploy to FastAPI Cloud まで成功している

次に、わざとバグを入れてみる。 main.py の戻り値を {"result": x + 2} に変えて push すると、 Run tests で失敗して Deploy to FastAPI Cloud は実行されない。壊れたコードがデプロイされることはない。

Actions の実行結果。Run tests が失敗して Deploy to FastAPI Cloud がスキップされている


fastapi cloud setup-ci で一発セットアップ

fastapi cloud setup-ci コマンドを使えば、ここまでの「トークンを作る → Secrets に登録 → ワークフローを書く」を、1コマンドで全部やってくれる。
cf. Setup CI Command - FastAPI Cloud

前提は3つ。

  • fastapi login 済みであること
  • 一度 fastapi deploy していて、アプリがディレクトリにリンク済みであること
  • リモート origin が GitHub リポジトリであること

実行すると確認プロンプトが2回出るけど、どちらもデフォルトの Yes のまま Enter で進めばいい。

% uv run fastapi cloud setup-ci

  Configuring CI

 ⚙️ Setting up CI for my-account/my-repository (branch: main)

    Create a FastAPI Cloud deploy token for GitHub Actions? Yes

 🔑 Created deploy token

    Set GitHub Actions secrets FASTAPI_CLOUD_TOKEN and FASTAPI_CLOUD_APP_ID via gh? Yes

 🔒 Set GitHub Actions secrets FASTAPI_CLOUD_TOKEN and FASTAPI_CLOUD_APP_ID

    Wrote .github/workflows/deploy.yml (branch: main)

 ✅ Done! Commit and push to start deploying.

    Your deploy token expires on 2027-07-15. Regenerate it from the dashboard or re-run this command before then.

やってくれること。

  • デプロイトークンの作成(有効期限 365 日。切れる前にダッシュボードで再生成するか、このコマンドをもう一度実行する)
  • GitHub Secrets の登録(gh CLI が認証済みならそのまま登録してくれる。なければ値が表示されるので手動で登録する)
  • .github/workflows/deploy.yml の生成(ファイル名は --file で変えられる)

生成されたワークフローファイル:

.github/workflows/deploy.yml
name: Deploy to FastAPI Cloud
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: astral-sh/setup-uv@v7
      - run: uv run fastapi deploy
        env:
          FASTAPI_CLOUD_TOKEN: ${{ secrets.FASTAPI_CLOUD_TOKEN }}
          FASTAPI_CLOUD_APP_ID: ${{ secrets.FASTAPI_CLOUD_APP_ID }}

生成されたワークフローは「push したらデプロイ」だけで、テストのステップは入ってない。テストが通ったらデプロイにするなら、上に書いた .github/workflows/ci-cd.yml のようにすればいい。

そのほかのオプションもある。

  • --dry-run … 何をするか表示するだけで、実行はしない
  • --secrets-only … トークン作成と Secrets 登録だけ(ワークフローファイルは書かない)
  • --workflow-only … ワークフローファイルの生成だけ(トークン作成と Secrets 登録はしない)
  • --branch … デプロイを引き起こすブランチの指定(デフォルトはリポジトリのデフォルトブランチ)