Skip to content

デプロイ

本番環境にデプロイする時に FastAPI アプリを起動する方法とかデプロイの自動化とか。
一番楽なのは FastAPI Cloud を使うこと(コマンド 1 つでデプロイできる)だけど、このページではオンプレのサーバーに自分でデプロイする方法をまとめる。

Info

uv のインストールが完了した Rocky Linux 9 にデプロイする前提で。


Uvicorn と Gunicorn

FastAPI をインストールしてれば、 Uvicorn も入ってるはず。

Note

fastapi dev コマンドと fastapi run コマンドは Uvicorn で FastAPI アプリを起動する。

ただ、 Uvicorn の公式ドキュメントで

Run gunicorn -k uvicorn.workers.UvicornWorker for production.

https://uvicorn.dev/deployment/ より

とあるので、 Gunicorn を使う。
さらに、 Uvicorn の公式ドキュメントには gunicorn で uvicorn ワーカーを使うときは、 uvicorn-worker を使うべきって書いてある。

Warning

The uvicorn.workers module is deprecated and will be removed in a future release. You should use the uvicorn-worker package instead.

python -m pip install uvicorn-worker

https://uvicorn.dev/deployment/#gunicorn より

uvicorn-worker を PyPI で検索すると、 gunicorn コマンドで使う時の例が書かれてる。

Deployment

For production environments, it's recommended to utilize Gunicorn with the Uvicorn worker class. Below is an example of how to do this:

gunicorn example:app -w 4 -k uvicorn_worker.UvicornWorker

https://uvicorn.dev/deployment/#gunicorn より

Gunicorn を uvicorn-worker で動かすために uv コマンドでインストールしておく。

uv add gunicorn uvicorn-worker


Gunicorn の起動設定

gunicorn コマンドで FastAPI アプリを起動する。

uv run gunicorn -w 3 -k uvicorn_worker.UvicornWorker -b 0.0.0.0:8000 main:app

毎回このコマンドを打つのはめんどい・・・コンフィグファイルを作成して、起動時に読み込ませることができる。

gunicorn_config.py
import multiprocessing

worker_class = "uvicorn_worker.UvicornWorker" 
workers = multiprocessing.cpu_count() * 2 + 1
bind = "0.0.0.0:8000" 

FastAPI Cookbook (by Giunio De Luca, 2024)

A common heuristic is to use the formula workers = (2 x cores) + 1 , where cores means the number of CPU cores on the server.
— p.313

とあるので、 multiprocessing を使って上のように自動で計算させてもいいのかも。

サーバー証明書(HTTPS)の設定

gunicorn_config.pykeyfile(秘密鍵)と certfile(証明書)のパスを書いておけば、 Gunicorn が直接 HTTPS で配信できる: cf. Gunicorn の SSL 設定

gunicorn_config.py
keyfile = "/etc/ssl/private/server.key"
certfile = "/etc/ssl/certs/server.crt"

コマンドラインで起動するなら --keyfile--certfile でも指定できる。

gunicorn コマンドで gunicorn_config.py を読み込んで FastAPI アプリを起動する。

uv run gunicorn -c gunicorn_config.py main:app

Gunicorn はデーモンモード( -D, daemon = True)で起動することもできるけど、停止する時に kill コマンドを使う方法しか分からなくて微妙。 systemd で起動・停止できるようにも設定できるので、 systemd の設定ファイルを作成する。

vi /etc/systemd/system/fastapi-app.service

/etc/systemd/system/fastapi-app.service
[Unit]
Description=Gunicorn instance to serve FastAPI App
After=network.target

[Service]
User=alice
Group=alice
WorkingDirectory=/home/alice/my-fastapi-app
ExecStart=/home/alice/.local/bin/uv run gunicorn -c gunicorn_config.py app.main:app
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
systemctl daemon-reload

これで、 systemctl コマンドで fastapi-app サービスを起動・停止できるようになる。


GitHub Actions を使った CD (Continuous Deploy) 実装

プロジェクトを GitHub でバージョン管理してるなら、 GitHub Actions を使ってデプロイの自動化ができる。 .github/workflows/my-actions.yml のようなパスで YAML ファイルの作成が必要。 具体的にやることは GitHub Actions のページを参照。

Warning

バグった状態でデプロイしないためにも、GitHub Actions のページのようにデプロイの前に pytest でテストを実行して成功したらデプロイするっていう自動化プロセスにするべき。

Warning

GitHub Actions を狙った攻撃も実際にあった( https://tanstack.com/blog/npm-supply-chain-compromise-postmortem )ので、パブリックリポジトリで自動化するときは特に気をつけた方がいいはず。