コンテンツへスキップ

コンテナにおけるFastAPI - Docker

FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナイメージ**を構築することです。通常は**Docker**を使用して行われます。その後、そのコンテナイメージをいくつかの方法でデプロイできます。

Linuxコンテナを使用すると、**セキュリティ**、**再現性**、**シンプルさ**など、いくつかの利点があります。

ヒント

急いでいて、すでにこれらのことを知っている場合?下のDockerfile 👇にジャンプしてください。

Dockerfileプレビュー 👀
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カーネルを使用して実行されます。これは、コンテナが(オペレーティングシステム全体をエミュレートする完全な仮想マシンと比較して)非常に軽量であることを意味します。

このように、コンテナはプロセスを直接実行する場合と同等の少量のリソースしか消費しません(仮想マシンははるかに多くのリソースを消費します)。

コンテナには独自の**独立した**実行プロセス(通常は1つのプロセスのみ)、ファイルシステム、ネットワークもあり、デプロイ、セキュリティ、開発などを簡素化します。

コンテナイメージとは

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

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

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

**コンテナ**が開始されて実行されると(**コンテナイメージ**から開始)、ファイルや環境変数を変更したり作成したりすることがあります。これらの変更はそのコンテナ内でのみ存在し、基になるコンテナイメージには保持されません(ディスクに保存されません)。

コンテナイメージは、**プログラム**ファイルとそのコンテンツ(例:pythonとファイルmain.py)に匹敵します。

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

コンテナイメージ

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

そして、多くのツール、環境、データベース、およびアプリケーションのための事前に作成された**公式コンテナイメージ**が公開されている Docker Hub があります。

たとえば、公式の Python イメージ があります。

そして、データベースなど、さまざまなもののための多くの他のイメージがあります。たとえば

事前に作成されたコンテナイメージを使用することで、さまざまなツールを簡単に**組み合わせ**て使用できます。たとえば、新しいデータベースを試す場合などです。ほとんどの場合、**公式イメージ**を使用し、環境変数で設定するだけで済みます。

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

そのため、データベース、Pythonアプリケーション、Reactフロントエンドアプリケーションを含むWebサーバーなど、さまざまなコンポーネントを持つ**複数のコンテナ**を実行し、それらの内部ネットワークを介して接続します。

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

コンテナとプロセス

**コンテナイメージ**には、通常、メタデータに、**コンテナ**の起動時に実行されるべきデフォルトのプログラムまたはコマンド、およびそのプログラムに渡されるパラメータが含まれています。コマンドラインの場合と非常によく似ています。

**コンテナ**が起動されると、そのコマンド/プログラムが実行されます(ただし、上書きして異なるコマンド/プログラムを実行させることもできます)。

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

コンテナは通常**単一のプロセス**を持ちますが、メインプロセスからサブプロセスを起動することも可能であり、そのようにして同じコンテナに**複数プロセス**を持つことができます。

しかし、**少なくとも1つの実行中のプロセス**がない状態でコンテナを実行することはできません。メインプロセスが停止すると、コンテナも停止します。

FastAPI用のDockerイメージの構築

それでは、実際に何かを構築してみましょう! 🚀

**公式Python**イメージに基づいて、FastAPIの**Dockerイメージ**を**ゼロから**構築する方法を示します。

これは、たとえば、**ほとんどの場合**に行うべきことです。

  • **Kubernetes**や同様のツールを使用する場合
  • **Raspberry Pi**で実行する場合
  • コンテナイメージを実行するクラウドサービスを使用する場合など。

パッケージ要件

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

それは主に、これらの要件を**インストール**するために使用するツールによって異なります。

最も一般的な方法は、パッケージ名とそのバージョンを1行に1つずつ記述した`requirements.txt`というファイルを持つことです。

FastAPIのバージョンの詳細で読んだのと同じ考え方を用いて、バージョンの範囲を設定します。

たとえば、`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

情報

パッケージ依存関係を定義およびインストールするための他の形式とツールがあります。

**FastAPI**コードの作成

  • `app`ディレクトリを作成して、そのディレクトリに入ります。
  • 空のファイル`__init__.py`を作成します。
  • `main.py`ファイルを作成し、以下を記述します。
from typing import Union

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: Union[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`を再度実行する場合のみですが、コンテナを使用している場合はそうではありません。

    注記

    `--no-cache-dir`は`pip`のみに関連しており、Dockerやコンテナとは関係ありません。

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

    ファイルのコピーという前のステップは**Dockerキャッシュ**によって検出される可能性があるため、このステップも可能な限り**Dockerキャッシュ**を使用します。

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

  5. `./app`ディレクトリを`/code`ディレクトリ内にコピーします。

    これはコード全体を含んでいるため、最も頻繁に変更される部分であり、Dockerの**キャッシュ**はこのステップ以降では簡単に使用できません。

    そのため、コンテナイメージの構築時間を最適化するために、これを`Dockerfile`の**最後の方**に配置することが重要です。

  6. コマンドを`fastapi run`(内部でUvicornを使用)を使用するように設定します。

    `CMD`は文字列のリストを受け取ります。これらの文字列はそれぞれ、コマンドラインでスペースで区切られたものと同じです。

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

ヒント

コード内の各番号の吹き出しをクリックして、各行が何をするかを確認してください。👆

警告

以下に説明するように、**常に**`CMD`命令の**exec形式**を使用してください。

`CMD` - Exec形式の使用

`CMD` Docker命令は、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が正常にシャットダウンし、ライフスパンイベントがトリガーされるように、常に**exec**形式を使用してください。

詳細については、シェルとexec形式に関するDockerドキュメントを参照してください。

`docker compose`を使用する場合、これは非常に顕著になります。より技術的な詳細については、このDocker Compose FAQセクションを参照してください。なぜ私のサービスは再作成または停止に10秒かかるのですか?

ディレクトリ構造

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

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

TLS終端プロキシの背後

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

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

Dockerキャッシュ

この`Dockerfile`には重要なトリックがあります。最初に、他のコードではなく、**依存関係のみのファイル**をコピーします。その理由を説明しましょう。

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

Dockerやその他のツールは、これらのコンテナイメージを**増分的に**構築し、`Dockerfile`の一番上から始め、`Dockerfile`の各命令によって作成されたファイルを上に**レイヤーを重ねて**追加します。

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

ファイルのコピーを回避するだけでは、必ずしも状況が大幅に改善するわけではありませんが、そのステップでキャッシュを使用することで、**次のステップでもキャッシュを使用できる**ようになります。たとえば、`pip`を使用して依存関係をインストールする命令でキャッシュを使用できます。

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%

ヒント

末尾の`.`は`./`と同じです。これは、コンテナイメージを構築するために使用するディレクトリをDockerに指示します。

この場合は、同じ現在のディレクトリ(`.`)です。

Dockerコンテナの起動

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

確認

DockerコンテナのURLで確認できます。たとえば、http://192.168.99.100/items/5?q=somequeryまたはhttp://127.0.0.1/items/5?q=somequery(または同等のもの、Dockerホストを使用)です。

次のようなものが表示されます。

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

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

http://192.168.99.100/docsまたはhttp://127.0.0.1/docs(または同等のもの、Dockerホストを使用)にアクセスできます。

(Swagger UIによって提供される)自動インタラクティブAPIドキュメントが表示されます。

Swagger UI

代替APIドキュメント

http://192.168.99.100/redocまたはhttp://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 アプリを起動する方法を認識します。😎

デプロイメントの概念

コンテナの観点から、同じデプロイメントの概念 について改めて説明しましょう。

コンテナは主に、アプリケーションの**構築とデプロイ**のプロセスを簡素化するためのツールですが、これらの**デプロイメントの概念**を処理する特定のアプローチを強制するものではなく、いくつかの可能な戦略があります。

**朗報**です。それぞれの戦略には、すべてのデプロイメントの概念を網羅する方法があります。🎉

コンテナの観点から、これらの**デプロイメントの概念**を確認しましょう。

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

HTTPS

FastAPI アプリケーションの**コンテナイメージ**(そして後述する実行中の**コンテナ**)に焦点を当てると、HTTPS は通常、別のツールによって**外部的に**処理されます。

例えば、Traefik を使用した別のコンテナが**HTTPS**と**自動的な****証明書**取得を処理する場合があります。

ヒント

Traefik は Docker、Kubernetes などと統合されているため、これを使用してコンテナの HTTPS を簡単に設定できます。

あるいは、クラウドプロバイダがそのサービスの1つとして HTTPS を処理する場合もあります(アプリケーションはコンテナ内で実行したまま)。

起動時と再起動の実行

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

それは、**Docker**、**Docker Compose**、**Kubernetes**、**クラウドサービス**などです。

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

コンテナを使用せずに、アプリケーションを起動時に実行し、再起動できるようにすることは、面倒で困難な場合があります。しかし、**コンテナを使用する場合**、その機能はほとんどの場合、デフォルトで含まれています。✨

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

**Kubernetes**、Docker Swarm Mode、Nomad、または複数のマシン上の分散コンテナを管理する同様の複雑なシステムを使用してマシンをクラスタ化している場合、各コンテナでプロセス マネージャー(Uvicorn とワーカーなど)を使用する代わりに、**クラスタレベル**で**レプリケーション**を処理することをお勧めします。

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

そのような場合、上記の説明にあるように、依存関係をインストールして**単一の Uvicorn プロセス**を実行する**Docker イメージをゼロから構築**することをお勧めします。

ロードバランサー

コンテナを使用する場合、通常、メインポートで**リスニングする**コンポーネントがあります。それは、**HTTPS**を処理する**TLS ターミネーション プロキシ**でもある別のコンテナ、または同様のツールである可能性があります。

このコンポーネントはリクエストの**負荷**を受け持ち、それをワーカー間に(うまくいけば)**バランスの取れた**方法で分散するため、**ロードバランサー**と呼ばれることも一般的です。

ヒント

HTTPS に使用される同じ**TLS ターミネーション プロキシ**コンポーネントは、おそらく**ロードバランサー**でもあります。

また、コンテナを使用する場合、それらを起動および管理するために使用するシステムには、その**ロードバランサー**(**TLS ターミネーション プロキシ**でもある可能性があります)からアプリケーションを含むコンテナへの**ネットワーク通信**(例:HTTP リクエスト)を伝送するための内部ツールが既に備わっています。

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

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

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

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

そして、通常、この**ロードバランサー**は、クラスタ内の*他の*アプリ(例:異なるドメイン、または異なる URL パス接頭辞の下)にアクセスするリクエストを処理し、その通信をクラスタ内で実行されている*他の*アプリケーションの適切なコンテナに伝送できます。

コンテナごとに1つのプロセス

この種のシナリオでは、おそらく**コンテナごとに1つの(Uvicorn)プロセス**を持つ方が良いでしょう。クラスタレベルでレプリケーションを既に処理しているからです。

したがって、この場合、コマンドラインオプション--workersを使用して複数のワーカーをコンテナに持たせることは**しません**。コンテナごとに**単一の Uvicorn プロセス**を持つ方が良いでしょう(ただし、複数のコンテナを持つ可能性があります)。

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

複数のプロセスと特別なケースを持つコンテナ

もちろん、**複数の 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. ワーカー数を4に設定する例を以下に示します。

それが理にかなう場合の例をいくつか示します。

シンプルなアプリ

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

Docker Compose

**Docker Compose**を使用して**単一サーバー**(クラスタではない)にデプロイする場合、共有ネットワークと**ロードバランシング**を維持しながら、コンテナのレプリケーションを(Docker Composeで)簡単に管理する方法がありません。

そのため、内部で**複数のワーカープロセス**を起動する**プロセス マネージャー**を持つ**単一コンテナ**が必要になる場合があります。


重要な点は、これらは盲目的に従わなければならない**不変のルール**ではないということです。これらのアイデアを使用して**独自のユースケースを評価**し、システムに最適なアプローチを決定し、以下の概念の管理方法を確認できます。

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

メモリ

**コンテナごとに1つのプロセス**を実行する場合、これらのコンテナ(レプリケートされている場合は複数)それぞれによって消費されるメモリ量は、多かれ少なかれ明確で安定しており、制限されます。

そして、コンテナ管理システムの構成(例えば、**Kubernetes**)で、同じメモリ制限と要件を設定できます。このようにして、必要なメモリ量とクラスタ内のマシンの使用可能なメモリ量を考慮して、**使用可能なマシン**に**コンテナをレプリケート**できます。

アプリケーションが**シンプル**な場合、これはおそらく**問題にはなりません**し、ハードメモリ制限を指定する必要はないかもしれません。しかし、(例えば、**機械学習**モデルを使用して)**多くのメモリを使用している**場合は、消費しているメモリ量を確認し、**各マシン**で実行される**コンテナの数**を調整し(そしてクラスタにマシンを追加する可能性があります)。

**コンテナごとに複数のプロセス**を実行する場合は、起動されたプロセスの数が使用可能なメモリ量を**超過**しないようにする必要があります。

開始前の手順とコンテナ

コンテナ(例:Docker、Kubernetes)を使用している場合、使用できる主なアプローチは2つあります。

複数のコンテナ

**複数のコンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(例:**Kubernetes**クラスタ)、おそらく**別々のコンテナ**で**前の手順**の作業を行い、単一のプロセスを実行する単一コンテナで、レプリケートされたワーカーコンテナを実行する**前**に実行します。

情報

Kubernetes を使用している場合、これはおそらくInit Containerになります。

ご使用のユースケースにおいて、これらの前の手順を並列に複数回実行することに問題がない場合(たとえば、データベースのマイグレーションを実行するのではなく、データベースの準備が完了しているかどうかをチェックする場合など)、各コンテナ内のメインプロセスを開始する直前にそれらを追加することもできます。

単一コンテナ

複数のワーカープロセス(または単一のプロセス)を開始する単一コンテナで構成されるシンプルな設定の場合、アプリのプロセスを開始する直前に、同じコンテナ内でこれらの前の手順を実行できます。

ベースDockerイメージ

以前は、公式のFastAPI Dockerイメージがありました:tiangolo/uvicorn-gunicorn-fastapi。しかし、現在は非推奨となっています。⛔️

このベースDockerイメージ(または同様のもの)を使用することはお勧めしません

Kubernetes(またはその他)を使用しており、複数のコンテナでクラスタレベルでレプリケーションを設定している場合。そのような場合は、上記のように新規にイメージを構築することが最適です:FastAPI用Dockerイメージの構築

複数のワーカーが必要な場合は、--workersコマンドラインオプションを使用するだけで済みます。

技術詳細

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

しかし、現在Uvicorn(およびfastapiコマンド)は--workersの使用をサポートしているため、独自のDockerイメージを構築する代わりにベースDockerイメージを使用する理由はなくなりました(コード量はほぼ同じです😅)。

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

コンテナ(Docker)イメージを作成したら、それをデプロイする方法はいくつかあります。

例えば

  • 単一サーバーでDocker Composeを使用する
  • Kubernetesクラスタを使用する
  • Docker Swarm Modeクラスタを使用する
  • Nomadなどの他のツールを使用する
  • コンテナイメージを受け入れてデプロイするクラウドサービスを使用する

uvを使用したDockerイメージ

uvを使用してプロジェクトをインストールおよび管理する場合は、uv Dockerガイドに従ってください。

まとめ

コンテナシステム(例:DockerKubernetes)を使用すると、すべてのデプロイメントの概念を非常に簡単に処理できます。

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

ほとんどの場合、ベースイメージを使用せず、代わりに公式のPython Dockerイメージに基づいて新規にコンテナイメージを構築することをお勧めします。

Dockerfileの命令の順序Dockerキャッシュに注意することで、ビルド時間を最小限に抑え、生産性を最大化できます(退屈さを回避できます)。😎