fastapi/docs/ja/docs/deployment/docker.md

38 KiB
Raw Blame History

コンテナ内のFastAPI - Docker

FastAPIアプリケーションをデプロイする場合、一般的なアプローチはLinuxコンテナ・イメージをビルドすることです。基本的には Dockerを用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。

Linuxコンテナの使用には、セキュリティ反復可能性(レプリカビリティ)シンプリシティなど、いくつかの利点があります。

/// tip | 豆知識

お急ぎで、すでにこれらの情報をご存じですか? 以下のDockerfileの箇所👇へジャンプしてください。

///

Dockerfile Preview 👀
FROM python:3.9

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

COPY ./app /code/app

CMD ["fastapi", "run", "app/main.py", "--port", "80"]

# If running behind a proxy like Nginx or Traefik add --proxy-headers
# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"]

コンテナとは何か

コンテナ主にLinuxコンテナは、同じシステム内の他のコンテナ他のアプリケーションやコンポーネントから隔離された状態を保ちながら、すべての依存関係や必要なファイルを含むアプリケーションをパッケージ化する非常に軽量な方法です。

Linuxコンテナは、ホストマシン、仮想マシン、クラウドサーバーなどの同じLinuxカーネルを使用して実行されます。これは、OS全体をエミュレートする完全な仮想マシンと比べて非常に軽量であることを意味します。

このように、コンテナはリソースをほとんど消費しませんが、プロセスを直接実行するのに匹敵する量です(仮想マシンはもっと消費します)。

コンテナはまた、独自の分離された実行プロセス通常は1つのプロセスのみや、ファイルシステム、ネットワークを持ちます。 このことはデプロイ、セキュリティ、開発などを簡素化させます。

コンテナ・イメージとは何か

コンテナは、コンテナ・イメージから実行されます。

コンテナ・イメージは、コンテナ内に存在すべきすべてのファイルや環境変数、そしてデフォルトのコマンド/プログラムを静的にバージョン化したものです。 ここでの静的とは、コンテナイメージは実行されておらず、パッケージ化されたファイルとメタデータのみであることを意味します。

保存された静的コンテンツである「コンテナイメージ」とは対照的に、「コンテナ」は通常、実行中のインスタンス、つまり実行されているものを指します。

コンテナが起動され実行されるとき(コンテナイメージから起動されるとき)、ファイルや環境変数などが作成されたり変更されたりする可能性があります。これらの変更はそのコンテナ内にのみ存在しますが、基盤となるコンテナ・イメージには残りません(ディスクに保存されません)。

コンテナイメージは プログラム ファイルやその内容、例えば pythonmain.py ファイルに匹敵します。

そして、コンテナ自体は(コンテナイメージとは対照的に)イメージをもとにした実際の実行中のインスタンスであり、プロセスに匹敵します。実際、コンテナが実行されているのは、プロセスが実行されているときだけです(通常は単一のプロセスだけです)。 コンテナ内で実行中のプロセスがない場合、コンテナは停止します。

コンテナ・イメージ

Dockerは、コンテナ・イメージコンテナを作成・管理するための主要なツールの1つです。

そして、多くのツールや環境、データベース、アプリケーションに対応している予め作成された公式のコンテナ・イメージをパブリックに提供しているDocker Hubというものがあります。

例えば、公式イメージの1つにPython Imageがあります。

その他にも、データベースなどさまざまなイメージがあります:

予め作成されたコンテナ・イメージを使用することで、異なるツールを組み合わせて使用することが非常に簡単になります。例えば、新しいデータベースを試す場合に特に便利です。ほとんどの場合、公式イメージを使い、環境変数で設定するだけで良いです。

そうすれば多くの場合、コンテナとDockerについて学び、その知識をさまざまなツールやコンポーネントによって再利用することができます。

つまり、データベース、Pythonアプリケーション、Reactフロントエンド・アプリケーションを備えたウェブ・サーバーなど、さまざまなものを複数のコンテナで実行し、それらを内部ネットワーク経由で接続します。

すべてのコンテナ管理システムDockerやKubernetesなどには、こうしたネットワーキング機能が統合されています。

コンテナとプロセス

通常、コンテナ・イメージはそのメタデータにコンテナの起動時に実行されるデフォルトのプログラムまたはコマンドと、そのプログラムに渡されるパラメータを含みます。コマンドラインでの操作とよく似ています。

コンテナが起動されると、そのコマンド/プログラムが実行されます(ただし、別のコマンド/プログラムをオーバーライドして実行させることもできます)。

コンテナは、メイン・プロセス(コマンドまたはプログラム)が実行されている限り実行されます。

コンテナは通常1つのプロセスを持ちますが、メイン・プロセスからサブ・プロセスを起動することも可能で、そうすれば同じコンテナ内に複数のプロセスを持つことになります。

しかし、少なくとも1つの実行中のプロセスがなければ、実行中のコンテナを持つことはできないです。メイン・プロセスが停止すれば、コンテナも停止します。

FastAPI用のDockerイメージをビルドする

ということで、何か作りましょう!🚀

FastAPI用のDockerイメージを、公式Pythonイメージに基づいてゼロからビルドする方法をお見せします。

これはほとんどの場合にやりたいことです。例えば:

  • Kubernetesまたは同様のツールを使用する場合
  • Raspberry Piで実行する場合
  • コンテナ・イメージを実行してくれるクラウド・サービスなどを利用する場合

パッケージ要件

アプリケーションのパッケージ要件は通常、何らかのファイルに記述されているはずです。

パッケージ要件は主にインストールするために使用するツールに依存するでしょう。

最も一般的な方法は、requirements.txt ファイルにパッケージ名とそのバージョンを 1 行ずつ書くことです。

もちろん、FastAPI バージョンについて{.internal-link target=_blank}で読んだのと同じアイデアを使用して、バージョンの範囲を設定します。

例えば、requirements.txt は次のようになります:

fastapi[standard]>=0.113.0,<0.114.0
pydantic>=2.7.0,<3.0.0

そして通常、例えば pip を使ってこれらのパッケージの依存関係をインストールします:

$ pip install -r requirements.txt
---> 100%
Successfully installed fastapi pydantic

/// info | 情報

パッケージの依存関係を定義しインストールするためのフォーマットやツールは他にもあります。

///

FastAPIコードを作成する

  • app ディレクトリを作成し、その中に入ります。
  • 空のファイル __init__.py を作成します。
  • 次の内容で main.py ファイルを作成します:
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

Dockerfile

同じプロジェクト・ディレクトリにDockerfileというファイルを作成します:

# (1)!
FROM python:3.9

# (2)!
WORKDIR /code

# (3)!
COPY ./requirements.txt /code/requirements.txt

# (4)!
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

# (5)!
COPY ./app /code/app

# (6)!
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
  1. 公式のPythonベースイメージから始めます

  2. 現在の作業ディレクトリを /code に設定します

    ここに requirements.txt ファイルと app ディレクトリを置きます。

  3. 要件が書かれたファイルを /code ディレクトリにコピーします

    残りのコードではなく、最初に必要なファイルだけをコピーしてください。

    このファイルは頻繁には変更されないので、Dockerはこのステップではそれを検知しキャッシュを使用し、次のステップでもキャッシュを有効にします。

  4. 要件ファイルにあるパッケージの依存関係をインストールします

    --no-cache-dir オプションはダウンロードしたパッケージをローカルに保存しないように pip に指示します。これは、同じパッケージをインストールするために pip を再度実行する場合にのみ有効ですが、コンテナで作業する場合はそうではないです。

    /// note | 備考

    --no-cache-dirpipに関連しているだけで、Dockerやコンテナとは何の関係もないです。

    ///

    --upgrade オプションは、パッケージが既にインストールされている場合、pip にアップグレードするように指示します。

    何故ならファイルをコピーする前のステップはDockerキャッシュによって検出される可能性があるためであり、このステップも利用可能な場合はDockerキャッシュを使用します。

    このステップでキャッシュを使用すると、開発中にイメージを何度もビルドする際に、毎回すべての依存関係をダウンロードしてインストールする代わりに多くの時間節約できます。

  5. ./app ディレクトリを /code ディレクトリの中にコピーする。

    これには最も頻繁に変更されるすべてのコードが含まれているため、Dockerのキャッシュこれ以降のステップに簡単に使用されることはありません。

    そのため、コンテナイメージのビルド時間を最適化するために、Dockerfile最後 にこれを置くことが重要です。

  6. 内部でUvicornを使用する fastapi run を使うためのコマンドを設定します

    CMD は文字列のリストを取り、それぞれの文字列はスペースで区切られたコマンドラインに入力するものです。

    このコマンドは 現在の作業ディレクトリから実行され、上記の WORKDIR /code にて設定した /code ディレクトリと同じです。

/// tip | 豆知識

コード内の各番号バブルをクリックして、各行が何をするのかをレビューしてください。👆

///

/// warning | 注意

以下で説明する通り、CMD 命令は常に exec形式を使用してください。

///

CMD を使う - Exec形式

Docker命令 CMD は2つの形式で書けます

Exec 形式:

# ✅ Do this
CMD ["fastapi", "run", "app/main.py", "--port", "80"]

Shell 形式:

# ⛔️ Don't do this
CMD fastapi run app/main.py --port 80

FastAPIが正常にシャットダウンでき、lifespan events{.internal-link target=_blank}がトリガーされるように、常に exec 形式を使用してください。

詳しくは、shell形式とexec形式に関するDockerドキュメントをご覧ください。

これは docker compose を使用する場合にかなり目立つことがあります。より技術的な詳細は、このDocker ComposeのFAQセクションをご覧くださいWhy do my services take 10 seconds to recreate or stop?

ディレクトリ構造

これで、次のようなディレクトリ構造になるはずです:

.
├── app
│   ├── __init__.py
│   └── main.py
├── Dockerfile
└── requirements.txt

TLS Termination Proxyの裏側

Nginx や Traefik のような TLS Termination Proxy (ロードバランサ) の後ろでコンテナを動かしている場合は、--proxy-headersオプションを追加します。これにより、FastAPI CLI経由でUvicornに対して、そのプロキシから送信されるヘッダを信頼し、アプリケーションがHTTPSの裏で実行されていることなどを示すよう指示します。

CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]

Dockerキャッシュ

このDockerfileには重要なトリックがあり、まず依存関係だけのファイルをコピーします。その理由を説明します。

COPY ./requirements.txt /code/requirements.txt

Dockerや他のツールは、これらのコンテナイメージを段階的にビルドし、1つのレイヤーを他のレイヤーの上に追加します。Dockerfileの先頭から開始し、Dockerfileの各命令によって作成されたファイルを追加していきます。

Dockerや同様のツールは、イメージをビルドする際に内部キャッシュも使用します。前回コンテナイメージを構築したときからファイルが変更されていない場合、ファイルを再度コピーしてゼロから新しいレイヤーを作成する代わりに、前回作成した同じレイヤーを再利用します。

ただファイルのコピーを避けるだけではあまり改善されませんが、そのステップでキャッシュを利用したため、次のステップでキャッシュを使うことができます。

例えば、依存関係をインストールする命令のためにキャッシュを使うことができます:

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

パッケージ要件のファイルは頻繁に変更されることはありません。そのため、そのファイルだけをコピーすることで、Dockerはそのステップではキャッシュを使用することができます。

そして、Dockerは次のステップのためにキャッシュを使用し、それらの依存関係をダウンロードしてインストールすることができます。そして、ここで多くの時間を節約します。 ...そして退屈な待ち時間を避けることができます。😪😆

パッケージの依存関係をダウンロードしてインストールするには数分かかりますが、キャッシュを使えばせいぜい数秒です。

加えて、開発中にコンテナ・イメージを何度もビルドして、コードの変更が機能しているかどうかをチェックすることになるため、多くの時間を節約することができます。

そしてDockerfileの最終行の近くですべてのコードをコピーします。この理由は、最も頻繁に変更されるものなので、このステップの後にあるものはほとんどキャッシュを使用することができないのためです。

COPY ./app /code/app

Dockerイメージをビルドする

すべてのファイルが揃ったので、コンテナ・イメージをビルドしましょう。

  • プロジェクトディレクトリに移動します(Dockerfileがある場所で、appディレクトリがあります)。
  • FastAPI イメージをビルドします:
$ docker build -t myimage .

---> 100%

/// tip | 豆知識

末尾の . に注目してほしいです。これは ./ と同じ意味です。 これはDockerにコンテナイメージのビルドに使用するディレクトリを指示します。

この場合、同じカレント・ディレクトリ(.)です。

///

Dockerコンテナの起動する

  • イメージに基づいてコンテナを実行します:
$ docker run -d --name mycontainer -p 80:80 myimage

確認する

Dockerコンテナのhttp://192.168.99.100/items/5?q=somequeryhttp://127.0.0.1/items/5?q=somequery (またはそれに相当するDockerホストを使用したものといったURLで確認できるはずです。

アクセスすると以下のようなものが表示されます:

{"item_id": 5, "q": "somequery"}

インタラクティブなAPIドキュメント

これらのURLにもアクセスできます: http://192.168.99.100/docshttp://127.0.0.1/docs (またはそれに相当するDockerホストを使用したもの

アクセスすると、自動対話型APIドキュメントSwagger UIが提供)が表示されます:

Swagger UI

代替のAPIドキュメント

また、http://192.168.99.100/redochttp://127.0.0.1/redoc (またはそれに相当するDockerホストを使用したものにもアクセスできます。

代替の自動ドキュメント(ReDocによって提供される)が表示されます:

ReDoc

単一ファイルのFastAPIでDockerイメージをビルドする

FastAPI が単一のファイル、例えば ./app ディレクトリのない main.py の場合、ファイル構造は次のようになります:

.
├── Dockerfile
├── main.py
└── requirements.txt

そうすれば、Dockerfileの中にファイルをコピーするために、対応するパスを変更するだけでよいです:

FROM python:3.9

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

# (1)!
COPY ./main.py /code/

# (2)!
CMD ["fastapi", "run", "main.py", "--port", "80"]
  1. main.pyファイルを /code ディレクトリに直接コピーします(./app ディレクトリなし)。

  2. 単一ファイル main.py 内のアプリケーションを配信するために fastapi run を使用します。

fastapi run にファイルを渡すと、それがパッケージの一部ではなく単一ファイルであることを自動的に検出し、インポートしてFastAPIアプリを配信する方法を判断します。😎

デプロイメントのコンセプト

コンテナという観点から、デプロイのコンセプト{.internal-link target=_blank}に共通するいくつかについて、もう一度説明しましょう。

コンテナは主に、アプリケーションのビルドとデプロイのプロセスを簡素化するためのツールですが、これらのデプロイのコンセプトを扱うための特定のアプローチを強制するものではなく、いくつかの戦略があります。

良いニュースは、それぞれの異なる戦略には、すべてのデプロイメントのコンセプトをカバーする方法があるということです。🎉

これらのデプロイメントのコンセプトをコンテナの観点から見直してみましょう:

  • HTTPS
  • 起動時の実行
  • 再起動
  • レプリケーション(実行中のプロセス数)
  • メモリ
  • 開始前の事前ステップ

HTTPS

FastAPI アプリケーションの コンテナ・イメージ(および後で実行中の コンテナだけに焦点を当てると、通常、HTTPSは別のツールを用いて外部で処理されます。

例えばTraefikのように、HTTPS証明書自動取得を扱う別のコンテナである可能性もあります。

/// tip | 豆知識

TraefikはDockerやKubernetesなどと統合されているので、コンテナ用のHTTPSの設定や構成はとても簡単です。

///

あるいは、コンテナ内でアプリケーションを実行しながらクラウド・プロバイダーがサービスの1つとしてHTTPSを処理することもできます。

起動時および再起動時の実行

通常、コンテナの起動と実行を担当する別のツールがあります。

それは直接Dockerであったり、Docker Composeであったり、Kubernetesであったり、クラウドサービスであったりします。

ほとんどの場合またはすべての場合、起動時にコンテナを実行し、失敗時に再起動を有効にする簡単なオプションがあります。例えばDockerでは、コマンドラインオプションの--restartが該当します。

コンテナを使わなければ、アプリケーションを起動時や再起動時に実行させるのは面倒で難しいかもしれません。しかし、コンテナで作業する場合、ほとんどのケースでその機能はデフォルトで含まれています。

レプリケーション - プロセス数

Kubernetes や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンのclusterを構成している場合、 各コンテナでWorkerを持つUvicornのようなプロセスマネージャを使用する代わりに、クラスター・レベルレプリケーションを処理したいと思うでしょう。

Kubernetesのような分散コンテナ管理システムの1つは通常、入ってくるリクエストのロードバランシングをサポートしながら、コンテナのレプリケーションを処理する統合された方法を持っています。このことはすべてクラスタレベルにてです。

そのような場合、上記の説明のようにDockerイメージをゼロからビルドし、依存関係をインストールして、単一のUvicornプロセスを実行したいでしょう。複数のUvicornワーカーを使う代わりにです。

ロードバランサー

コンテナを使用する場合、通常はメイン・ポートでリスニングしているコンポーネントがあるはずです。それはおそらく、HTTPSを処理するためのTLS Termination Proxyでもある別のコンテナであったり、同様のツールであったりするでしょう。

このコンポーネントはリクエストの 負荷 を受け、 (うまくいけば) その負荷をバランスよく ワーカーに分配するので、一般に ロードバランサ とも呼ばれます。

/// tip | 豆知識

HTTPSに使われるものと同じTLS Termination Proxyコンポーネントは、おそらくロードバランサーにもなるでしょう。

///

そしてコンテナで作業する場合、コンテナの起動と管理に使用する同じシステムには、ロードバランサーTLS Termination Proxyの可能性もある)からネットワーク通信HTTPリクエストなどをアプリのあるコンテナ複数可に送信するための内部ツールが既にあるはずです。

1つのロードバランサー - 複数のワーカーコンテナー

Kubernetesや同様の分散コンテナ管理システムで作業する場合、その内部のネットワーキングのメカニズムを使用することで、メインのポートでリッスンしている単一のロードバランサーが、アプリを実行している可能性のある複数のコンテナに通信(リクエスト)を送信できるようになります。

アプリを実行するこれらのコンテナには、通常1つのプロセスたとえば、FastAPIアプリケーションを実行するUvicornプロセスがあります。これらはすべて同一のコンテナであり同じものを実行しますが、それぞれが独自のプロセスやメモリなどを持ちます。そうすることで、CPUの異なるコア、あるいは異なるマシンでの並列化を利用できます。

そして、ロードバランサーを備えた分散コンテナシステムは、順番にあなたのアプリを含む各コンテナにリクエストを分配します。つまり、各リクエストは、あなたのアプリを実行している複数のレプリケートされたコンテナの1つによって処理されます。

そして通常、このロードバランサーは、クラスタ内の他のアプリケーション例えば、異なるドメインや異なるURLパスのプレフィックスの配下へのリクエストを処理することができ、その通信をクラスタ内で実行されている他のアプリケーションのための適切なコンテナに送信します。

1コンテナにつき1プロセス

この種のシナリオでは、すでにクラスタ・レベルでレプリケーションを処理しているため、おそらくコンテナごとに単一のUvicornプロセスを持ちたいでしょう。

この場合、例えばコマンドラインオプションの --workers で、コンテナ内に複数のワーカーを持つことは避けたいでしょう。コンテナごとにUvicornのプロセスは1つだけにしたいでしょう(おそらく複数のコンテナが必要でしょう)。

(複数のワーカーの場合のように)コンテナ内に別のプロセスマネージャーを持つことは、クラスターシステムですでに対処しているであろう不要な複雑さを追加するだけです。

複数プロセスのコンテナと特殊なケース

もちろん、特殊なケースとして、コンテナ内で複数のUvicornワーカープロセスを起動させたい場合があります。

そのような場合、--workers コマンドラインオプションを使って、実行したいワーカー数を設定できます:

FROM python:3.9

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

COPY ./app /code/app

# (1)!
CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
  1. ここでは --workers コマンドラインオプションを使って、ワーカー数を4に設定しています。

以下は、それが理にかなっている場合の例です:

シンプルなアプリ

アプリケーションが、クラスタではなく単一サーバで実行できるほどシンプルである場合、コンテナ内にプロセスマネージャが欲しくなることがあります。

Docker Compose

Docker Composeで単一サーバ(クラスタではない)にデプロイすることもできますので、共有ネットワークとロードバランシングを維持しながらDocker Composeでコンテナのレプリケーションを管理する簡単な方法はないでしょう。

その場合、単一のコンテナで、プロセスマネージャが内部で複数のワーカープロセスを起動するようにします。


重要なのは、これらのどれも、盲目的に従わなければならない「絶対的なルール」ではないということです。これらのアイデアは、あなた自身のユースケースを評価し、あなたのシステムに最適なアプローチを決定するために使用できます。次の概念をどう管理するかを確認してください:

  • セキュリティ - HTTPS
  • 起動時の実行
  • 再起動
  • レプリケーション(実行中のプロセス数)
  • メモリ
  • 開始前の事前ステップ

メモリ

コンテナごとに単一のプロセスを実行すると、それらのコンテナレプリケートされている場合は1つ以上によって消費される多かれ少なかれ明確に定義された、安定し制限された量のメモリを持つことになります。

そして、コンテナ管理システム(Kubernetesなど)の設定で、同じメモリ制限と要件を設定することができます。

そうすれば、コンテナが必要とするメモリ量とクラスタ内のマシンで利用可能なメモリ量を考慮して、利用可能なマシンコンテナをレプリケートできるようになります。

アプリケーションがシンプルなものであれば、これはおそらく問題にはならないでしょうし、ハードなメモリ制限を指定する必要はないかもしれないです。

しかし、多くのメモリを使用している場合(たとえば機械学習モデルなど)、どれだけのメモリを消費しているかを確認し、各マシンで実行するコンテナの数を調整する必要があります(そしておそらくクラスタにマシンを追加します)。

コンテナごとに複数のプロセスを実行する場合、起動するプロセスの数が利用可能なメモリ以上に消費しないようにする必要があります。

開始前の事前ステップとコンテナ

コンテナDockerやKubernetesなどを使っている場合、主に2つのアプローチがあります。

複数のコンテナ

複数のコンテナがあり、おそらくそれぞれが単一のプロセスを実行している場合(例えば、Kubernetesクラスタなど)、レプリケートされたワーカーコンテナを実行する前に、単一のコンテナで事前のステップの作業を行う別のコンテナを持ちたいと思うでしょう。

/// info | 情報

もしKubernetesを使用している場合, これはおそらくInit Containerでしょう。

///

ユースケースが事前のステップを並列で複数回実行するのに問題がない場合(例:データベースマイグレーションを実行するのではなく、データベースの準備ができたかをチェックするだけの場合)、メインプロセスを開始する直前に、それらのステップを各コンテナに入れることも可能です。

単一コンテナ

単純なセットアップで、単一のコンテナで複数のワーカープロセスまたは1つのプロセスのみを起動する場合、アプリでプロセスを開始する直前に、同じコンテナで事前のステップを実行できます。

ベースDockerイメージ

以前は、公式のFastAPI Dockerイメージがありましたtiangolo/uvicorn-gunicorn-fastapi。しかし、現在は非推奨です。

おそらく、このベースDockerイメージまたはその他の類似のもの使用しない方がよいでしょう。

すでにKubernetes(または他のもの)を使用していて、複数のコンテナで、クラスタレベルでレプリケーションを設定している場合。そのような場合は、上記で説明したようにゼロからイメージを構築する方がよいでしょう:FastAPI用のDockerイメージをビルドする

また、複数のワーカーが必要な場合は、単純に --workers コマンドラインオプションを使用できます。

/// note | 技術詳細

このDockerイメージは、Uvicornが停止したワーカーの管理と再起動をサポートしていなかった頃に作成されたため、Uvicornと一緒にGunicornを使う必要がありました。これは、GunicornにUvicornワーカープロセスの管理と再起動をさせるだけのために、かなりの複雑さを追加していました。

しかし現在は、Uvicornおよび fastapi コマンド)が --workers をサポートしているため、自分でビルドする代わりにベースDockerイメージを使う理由はありませんコード量もだいたい同じです 😅)。

///

コンテナ・イメージのデプロイ

コンテナDockerイメージを手に入れた後、それをデプロイするにはいくつかの方法があります。

例えば以下のリストの方法です:

  • 単一サーバーのDocker Compose
  • Kubernetesクラスタ
  • Docker Swarmモードのクラスター
  • Nomadのような別のツール
  • コンテナ・イメージをデプロイするクラウド・サービス

uv を使ったDockerイメージ

uv を使ってプロジェクトのインストールと管理をしている場合は、uv Docker guideに従ってください。

まとめ

コンテナ・システム(例えばDockerKubernetesなど)を使えば、すべてのデプロイメントのコンセプトを扱うのがかなり簡単になります:

  • HTTPS
  • 起動時の実行
  • 再起動
  • レプリケーション(実行中のプロセス数)
  • メモリ
  • 開始前の事前ステップ

ほとんどの場合、ベースとなるイメージは使用せず、公式のPython Dockerイメージをベースにしたコンテナイメージをゼロからビルドします。

DockerfileDockerキャッシュ内の命令の順番に注意することで、ビルド時間を最小化し、生産性を最大化できます(そして退屈を避けることができます)。😎