概要
nginxをリバースプロキシとして使ってhttpsを終端しながら、
uvicorn + FastAPIを使う場合のことを書いた記事です。
なんでこの記事を書いたか
serverディレクティブのproxy-passでFastAPIのサーバを指定するだけじゃ
FastAPIでOpenAPIのドキュメントが見れなかったので書きました。
ちなみにドキュメントのパスにアクセスすると以下みたいな画面になります。
Fetch error Not Found openapi.json
的なエラーが出る。
単にuvicorn + FastAPIをhttpsにするなら
uvicornの公式のhttpsの項 にあるように
uvicorn main:app --host 0.0.0.0 --ssl-keyfile ./cert/privkey.pem --ssl-certfile ./cert/cert.pem
な感じでいけます。
前提
- Nginxではポート8000でリクエストを待ち受けている
- uvicorn + FastAPIはポート8001で待ち受けている
- NginxとFastAPIは同じサーバで動いている
- Nginxに対する
https://FQDN名:8000/fastapi
へのアクセスを uvicorn+FastAPIのhttp://FQDN名:8001/
にプロキシする - 証明書は既にげっとん済み。
- fastAPIの主な設定はmain.pyに書いている
- 筆者はNginxのconfigをほぼ書いたことない
「あれでしょ、serverとかlocationとかのディレクティブに設定書いたり、
includeで他のファイルから設定を読み込めたりするんでしょ?」みたいなLv。
nginxのconfigを書く
serverディレクティブとして以下を追記する。
とりあえず、 /etc/nginx/sites-enabled/default
をコピーして
/etc/nginx/sites-enabled/fastapi
というファイルを作成。
その中にserverディレクティブと以下のコンテキストを作成。
server {
# fastapiへのリダイレクトと証明書の設定
listen 8000;
ssl_certificate /etc/letsencrypt/live/fastapi.tmktmk.tmk/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/fastapi.tmktmk.tmk/privkey.pem;
location /fastapi/ {
proxy_pass http://fastapi.tmktmk.tmk:8001/;
}
}
FastAPIにroot-pathを設定する
main.pyに以下を追記
from fastapi import Request #追加する。すでにFastAPIをimportしている行があるはずなのでそこに Request だけ追加する。
# 以下のようにroot_path=にnginxのlocationで記載したパスを記載する。
app = FastAPI(root_path="/fastapi")
アクセスしてみる
https://fastapi.tmktmk.tmk:8000/fastapi/docs
にアクセスする。
以下の感じでURLバーに鍵マークがついている事が分かります。
終わり
HTTPSでアクセスしたnginxを介してFastAPIにアクセスすることが出来ました。
ちなみに、nginxではなくHAProxyを使うとFastAPI側の設定を変えなくても、
haproxy.cfgのbackendのところに普通にFastAPIのサーバを設定するだけでこの記事と同じことが出来たりします。