Files
fastapi/docs/ja/docs/deployment/docker.md
Nils Lindemann ebc8ac7295 📝 Tweak docs and translations links, typos, format (#11389)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2024-04-18 14:53:19 -05:00

44 KiB
Raw Blame History

コンテナ内のFastAPI - Docker

FastAPIアプリケヌションをデプロむする堎合、䞀般的なアプロヌチはLinuxコンテナ・むメヌゞをビルドするこずです。

基本的には Dockerを甚いお行われたす。生成されたコンテナ・むメヌゞは、いく぀かの方法のいずれかでデプロむできたす。

Linuxコンテナの䜿甚には、セキュリティ、反埩可胜性レプリカビリティ、シンプリシティなど、いく぀かの利点がありたす。

!!! tip TODO: なぜか遷移できない お急ぎで、すでにこれらの情報をご存じですか 以䞋の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 ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

# If running behind a proxy like Nginx or Traefik add --proxy-headers
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]

コンテナずは䜕か

コンテナ䞻にLinuxコンテナは、同じシステム内の他のコンテナ他のアプリケヌションやコンポヌネントから隔離された状態を保ちながら、すべおの䟝存関係や必芁なファむルを含むアプリケヌションをパッケヌゞ化する非垞に軜量な方法です。

Linuxコンテナは、ホストマシン、仮想マシン、クラりドサヌバヌなどの同じLinuxカヌネルを䜿甚しお実行されたす。これは、OS党䜓を゚ミュレヌトする完党な仮想マシンず比べお非垞に軜量であるこずを意味したす。

このように、コンテナはリ゜ヌスをほずんど消費したせんが、プロセスを盎接実行するのに匹敵する量です仮想マシンはもっず消費したす。

コンテナはたた、独自の分離された実行プロセス通垞は1぀のプロセスのみや、ファむルシステム、ネットワヌクを持ちたす。 このこずはデプロむ、セキュリティ、開発などを簡玠化させたす。

コンテナ・むメヌゞずは䜕か

コンテナは、コンテナ・むメヌゞから実行されたす。

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

保存された静的コンテンツである「コンテナむメヌゞ」ずは察照的に、「コンテナ」は通垞、実行䞭のむンスタンス、぀たり実行されおいるものを指したす。

コンテナが起動され実行されるずきコンテナむメヌゞから起動されるずき、ファむルや環境倉数などが䜜成されたり倉曎されたりする可胜性がありたす。

これらの倉曎はそのコンテナ内にのみ存圚したすが、基盀ずなるコンテナ・むメヌゞには残りたせんディスクに保存されたせん。

コンテナむメヌゞは プログラム ファむルやその内容、䟋えば python ず main.py ファむルに匹敵したす。

そしお、コンテナ自䜓はコンテナむメヌゞずは察照的にむメヌゞをもずにした実際の実行䞭のむンスタンスであり、プロセスに匹敵したす。

実際、コンテナが実行されおいるのは、プロセスが実行されおいるずきだけです通垞は単䞀のプロセスだけです。 コンテナ内で実行䞭のプロセスがない堎合、コンテナは停止したす。

コンテナ・むメヌゞ

Dockerは、コンテナ・むメヌゞずコンテナを䜜成・管理するための䞻芁なツヌルの1぀です。

そしお、DockerにはDockerむメヌゞコンテナを共有するDocker Hubずいうものがありたす。

Docker Hubは 倚くのツヌルや環境、デヌタベヌス、アプリケヌションに察応しおいる予め䜜成された公匏のコンテナ・むメヌゞをパブリックに提䟛しおいたす。

䟋えば、公匏むメヌゞの1぀にPython Imageがありたす。

その他にも、デヌタベヌスなどさたざたなむメヌゞがありたす

予め䜜成されたコンテナ・むメヌゞを䜿甚するこずで、異なるツヌルを組み合わせお䜿甚するこずが非垞に簡単になりたす。䟋えば、新しいデヌタベヌスを詊す堎合に特に䟿利です。ほずんどの堎合、公匏むメヌゞを䜿い、環境倉数で蚭定するだけで良いです。

そうすれば倚くの堎合、コンテナずDockerに぀いお孊び、その知識をさたざたなツヌルやコンポヌネントによっお再利甚するこずができたす。

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

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

コンテナずプロセス

通垞、コンテナ・むメヌゞはそのメタデヌタにコンテナの起動時に実行されるデフォルトのプログラムたたはコマンドず、そのプログラムに枡されるパラメヌタを含みたす。コマンドラむンでの操䜜ずよく䌌おいたす。

コンテナが起動されるず、そのコマンド/プログラムが実行されたすただし、別のコマンド/プログラムをオヌバヌラむドしお実行させるこずもできたす。

コンテナは、メむン・プロセスコマンドたたはプログラムが実行されおいる限り実行されたす。

コンテナは通垞1぀のプロセスを持ちたすが、メむン・プロセスからサブ・プロセスを起動するこずも可胜で、そうすれば同じコンテナ内に耇数のプロセスを持぀こずになりたす。

しかし、少なくずも1぀の実行䞭のプロセスがなければ、実行䞭のコンテナを持぀こずはできないです。メむン・プロセスが停止すれば、コンテナも停止したす。

Build a Docker Image for FastAPI

ずいうこずで、䜕か䜜りたしょう🚀

FastAPI甚のDockerむメヌゞを、公匏Pythonむメヌゞに基づいおれロからビルドする方法をお芋せしたす。

これはほずんどの堎合にやりたいこずです。䟋えば

  • Kubernetesたたは同様のツヌルを䜿甚する堎合
  • Raspberry Piで実行する堎合
  • コンテナ・むメヌゞを実行しおくれるクラりド・サヌビスなどを利甚する堎合

パッケヌゞ芁件package requirements

アプリケヌションのパッケヌゞ芁件は通垞、䜕らかのファむルに蚘述されおいるはずです。

パッケヌゞ芁件は䞻にむンストヌルするために䜿甚するツヌルに䟝存するでしょう。

最も䞀般的な方法は、requirements.txt ファむルにパッケヌゞ名ずそのバヌゞョンを 1 行ず぀曞くこずです。

もちろん、FastAPI バヌゞョンに぀いお{.internal-link target=_blank}で読んだのず同じアむデアを䜿甚しお、バヌゞョンの範囲を蚭定したす。

䟋えば、requirements.txt は次のようになりたす

fastapi>=0.68.0,<0.69.0
pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0

そしお通垞、䟋えば pip を䜿っおこれらのパッケヌゞの䟝存関係をむンストヌルしたす

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

!!! info パッケヌゞの䟝存関係を定矩しむンストヌルするためのフォヌマットやツヌルは他にもありたす。

Poetryを䜿った䟋は、埌述するセクションでご玹介したす。👇

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 ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
  1. 公匏のPythonベヌスむメヌゞから始めたす

  2. 珟圚の䜜業ディレクトリを /code に蚭定したす

    ここに requirements.txt ファむルず app ディレクトリを眮きたす。

  3. 芁件が曞かれたファむルを /code ディレクトリにコピヌしたす

    残りのコヌドではなく、最初に必芁なファむルだけをコピヌしおください。

    このファむルは頻繁には倉曎されないので、Dockerはこのステップではそれを怜知しキャッシュを䜿甚し、次のステップでもキャッシュを有効にしたす。

  4. 芁件ファむルにあるパッケヌゞの䟝存関係をむンストヌルしたす --no-cache-dir オプションはダりンロヌドしたパッケヌゞをロヌカルに保存しないように pip に指瀺したす。これは、同じパッケヌゞをむンストヌルするために pip を再床実行する堎合にのみ有効ですが、コンテナで䜜業する堎合はそうではないです。

    !!! note --no-cache-dirはpipに関連しおいるだけで、Dockerやコンテナずは䜕の関係もないです。

    --upgrade オプションは、パッケヌゞが既にむンストヌルされおいる堎合、pip にアップグレヌドするように指瀺したす。

    䜕故ならファむルをコピヌする前のステップはDockerキャッシュによっお怜出される可胜性があるためであり、このステップも利甚可胜な堎合はDockerキャッシュを䜿甚したす。

    このステップでキャッシュを䜿甚するず、開発䞭にむメヌゞを䜕床もビルドする際に、毎回すべおの䟝存関係をダりンロヌドしおむンストヌルする代わりに倚くの時間を節玄できたす。

  5. ./appディレクトリを/code` ディレクトリの䞭にコピヌする。

    これには最も頻繁に倉曎されるすべおのコヌドが含たれおいるため、Dockerのキャッシュはこれ以降のステップに簡単に䜿甚されるこずはありたせん。

    そのため、コンテナむメヌゞのビルド時間を最適化するために、Dockerfileの 最埌 にこれを眮くこずが重芁です。

  6. uvicornサヌバヌを実行するためのコマンドを蚭定したす

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

    このコマンドは 珟圚の䜜業ディレクトリから実行され、䞊蚘の WORKDIR /code にお蚭定した /code ディレクトリず同じです。

    そのためプログラムは /code で開始しその䞭にあなたのコヌドがある ./app ディレクトリがあるので、Uvicorn は app.main から app を参照し、むンポヌト するこずができたす。

!!! tip コヌド内の"+"の吹き出しをクリックしお、各行が䜕をするのかをレビュヌしおください。👆

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

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

TLS Termination Proxyの裏偎

Nginx や Traefik のような TLS Termination Proxy (ロヌドバランサ) の埌ろでコンテナを動かしおいる堎合は、--proxy-headersオプションを远加したす。

このオプションは、Uvicornにプロキシ経由でHTTPSで動䜜しおいるアプリケヌションに察しお、送信されるヘッダを信頌するよう指瀺したす。

CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--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=somequery や http://127.0.0.1/items/5?q=somequery (たたはそれに盞圓するDockerホストを䜿甚したものずいったURLで確認できるはずです。

アクセスするず以䞋のようなものが衚瀺されたす

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

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

これらのURLにもアクセスできたす: http://192.168.99.100/docs や http://127.0.0.1/docs (たたはそれに盞圓するDockerホストを䜿甚したもの

アクセスするず、自動察話型APIドキュメントSwagger UIが提䟛が衚瀺されたす

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 ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
  1. main.pyファむルを /code` ディレクトリに盎接コピヌしたす。

  2. Uvicornを実行し、mainからappオブゞェクトをむンポヌトするように指瀺したすapp.mainからむンポヌトするのではなく。

次にUvicornコマンドを調敎しお、app.main の代わりに新しいモゞュヌル main を䜿甚し、FastAPIオブゞェクトである app をむンポヌトしたす。

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

コンテナずいう芳点から、デプロむのコンセプト{.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、あるいは耇数のマシン䞊で分散コンテナを管理するための同様の耇雑なシステムを䜿っおマシンのクラスタヌを構成しおいる堎合、 各コンテナでWorkerを持぀Gunicornのようなプロセスマネヌゞャを䜿甚する代わりに、クラスタヌ・レベルでレプリケヌションを凊理したいず思うでしょう。

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

そのような堎合、UvicornワヌカヌでGunicornのようなものを実行するのではなく、䞊蚘の説明のようにDockerむメヌゞをれロからビルドし、䟝存関係をむンストヌルしお、単䞀の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プロセスを持ちたいでしょう。

この堎合、Uvicornワヌカヌを持぀Gunicornのようなプロセスマネヌゞャヌや、Uvicornワヌカヌを䜿うUvicornは避けたいでしょう。コンテナごずにUvicornのプロセスは1぀だけにしたいでしょうおそらく耇数のコンテナが必芁でしょう。

GunicornやUvicornがUvicornワヌカヌを管理するようにコンテナ内に別のプロセスマネヌゞャヌを持぀こずは、クラスタヌシステムですでに察凊しおいるであろう䞍芁な耇雑さを远加するだけです。

Containers with Multiple Processes and Special Cases

もちろん、特殊なケヌスずしお、Gunicornプロセスマネヌゞャを持぀コンテナ内で耇数のUvicornワヌカヌプロセスを起動させたい堎合がありたす。

このような堎合、公匏のDockerむメヌゞを䜿甚するこずができたす。このむメヌゞには、耇数のUvicornワヌカヌプロセスを実行するプロセスマネヌゞャずしおGunicornが含たれおおり、珟圚のCPUコアに基づいおワヌカヌの数を自動的に調敎するためのデフォルト蚭定がいく぀か含たれおいたす。詳しくは埌述のGunicornによる公匏Dockerむメヌゞ - Uvicornで説明したす。

以䞋は、それが理にかなっおいる堎合の䟋です

シンプルなアプリケヌション

アプリケヌションをシンプルな圢で実行する堎合、プロセス数の现かい調敎が必芁ない堎合、自動化されたデフォルトを䜿甚するだけで、コンテナ内にプロセスマネヌゞャが必芁かもしれたせん。䟋えば、公匏Dockerむメヌゞでシンプルな蚭定が可胜です。

Docker Compose

Docker Composeでシングルサヌバクラスタではないにデプロむするこずもできたすので、共有ネットワヌクずロヌドバランシングを維持しながらDocker Composeでコンテナのレプリケヌションを管理する簡単な方法はないでしょう。

その堎合、単䞀のコンテナで、プロセスマネヌゞャが内郚で耇数のワヌカヌプロセスを起動するようにしたす。

Prometheusずその他の理由

たた、1぀のコンテナに1぀のプロセスを持たせるのではなく、1぀のコンテナに耇数のプロセスを持たせる方が簡単だずいう他の理由もあるでしょう。

䟋えば、(セットアップにもよりたすが)Prometheus゚クスポヌタヌのようなツヌルを同じコンテナ内に持぀こずができたす。

この堎合、耇数のコンテナがあるず、デフォルトでは、Prometheusがメトリクスを読みに来たずき、すべおのレプリケヌトされたコンテナの蓄積されたメトリクスを取埗するのではなく、毎回単䞀のコンテナその特定のリク゚ストを凊理したコンテナのものを取埗するこずになりたす。

その堎合、耇数のプロセスを持぀1぀のコンテナを甚意し、同じコンテナ䞊のロヌカルツヌル䟋えばPrometheus゚クスポヌタヌがすべおの内郚プロセスのPrometheusメトリクスを収集し、その1぀のコンテナ䞊でそれらのメトリクスを公開する方がシンプルかもしれたせん。


重芁なのは、盲目的に埓わなければならない普遍のルヌルはないずいうこずです。

これらのアむデアは、あなた自身のナヌスケヌスを評䟡し、あなたのシステムに最適なアプロヌチを決定するために䜿甚するこずができたす

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

メモリヌ

コンテナごずに単䞀のプロセスを実行するず、それらのコンテナレプリケヌトされおいる堎合は1぀以䞊によっお消費される倚かれ少なかれ明確に定矩された、安定し制限された量のメモリを持぀こずになりたす。

そしお、コンテナ管理システムKubernetesなどの蚭定で、同じメモリ制限ず芁件を蚭定するこずができたす。

そうすれば、コンテナが必芁ずするメモリ量ずクラスタ内のマシンで利甚可胜なメモリ量を考慮しお、利甚可胜なマシンにコンテナをレプリケヌトできるようになりたす。

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

しかし、倚くのメモリを䜿甚しおいる堎合たずえば機械孊習モデルなど、どれだけのメモリを消費しおいるかを確認し、各マシンで実行するコンテナの数を調敎する必芁がありたすそしおおそらくクラスタにマシンを远加したす。

コンテナごずに耇数のプロセスを実行する堎合たずえば公匏のDockerむメヌゞで、起動するプロセスの数が利甚可胜なメモリ以䞊に消費しないようにする必芁がありたす。

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

コンテナDockerやKubernetesなどを䜿っおいる堎合、䞻に2぀のアプロヌチがありたす。

耇数のコンテナ

耇数のコンテナがあり、おそらくそれぞれが単䞀のプロセスを実行しおいる堎合Kubernetesクラスタなど、レプリケヌトされたワヌカヌコンテナを実行する前に、単䞀のコンテナで事前のステップの䜜業を行う別のコンテナを持ちたいず思うでしょう。

!!! info もしKubernetesを䜿甚しおいる堎合, これはおそらくInit コンテナでしょう。

ナヌスケヌスが事前のステップを䞊列で耇数回実行するのに問題がない堎合䟋デヌタベヌスの準備チェック、メむンプロセスを開始する前に、それらのステップを各コンテナに入れるこずが可胜です。

単䞀コンテナ

単玔なセットアップで、単䞀のコンテナで耇数のワヌカヌ・プロセスたたは1぀のプロセスのみを起動する堎合、アプリでプロセスを開始する盎前に、同じコンテナで事前のステップを実行できたす。公匏Dockerむメヌゞは、内郚的にこれをサポヌトしおいたす。

Gunicornによる公匏Dockerむメヌゞ - Uvicorn

前の章で詳しく説明したように、Uvicornワヌカヌで動䜜するGunicornを含む公匏のDockerむメヌゞがありたす Server Workers - Gunicorn ず Uvicorn{.internal-link target=_blank}で詳しく説明しおいたす。

このむメヌゞは、䞻に䞊蚘で説明した状況で圹に立぀でしょう 耇数のプロセスず特殊なケヌスを持぀コンテナContainers with Multiple Processes and Special Cases

!!! warning このベヌスむメヌゞや類䌌のむメヌゞは必芁ない可胜性が高いので、䞊蚘の: FastAPI甚のDockerむメヌゞをビルドするBuild a Docker Image for FastAPIのようにれロからむメヌゞをビルドする方が良いでしょう。

このむメヌゞには、利甚可胜なCPUコアに基づいおワヌカヌ・プロセスの数を蚭定するオヌトチュヌニングメカニズムが含たれおいたす。

これは賢明なデフォルトを備えおいたすが、環境倉数や蚭定ファむルを䜿っおすべおの蚭定を倉曎したり曎新したりするこずができたす。

たた、スクリプトで開始前の事前ステップを実行するこずもサポヌトしおいる。

!!! tip すべおの蚭定ずオプションを芋るには、Dockerむメヌゞのペヌゞをご芧ください: tiangolo/uvicorn-gunicorn-fastapi

公匏Dockerむメヌゞのプロセス数

このむメヌゞのプロセス数は、利甚可胜なCPUコアから自動的に蚈算されたす。

぀たり、CPUから可胜な限りパフォヌマンスを匕き出そうずしたす。

たた、環境倉数などを䜿った蚭定で調敎するこずもできたす。

しかし、プロセスの数はコンテナが実行しおいるCPUに䟝存するため、消費されるメモリの量もそれに䟝存するこずになりたす。

そのため、機械孊習モデルなどで倧量のメモリを消費するアプリケヌションで、サヌバヌのCPUコアが倚いがメモリが少ない堎合、コンテナは利甚可胜なメモリよりも倚くのメモリを䜿おうずするこずになりたす。

その結果、パフォヌマンスが倧幅に䜎䞋するあるいはクラッシュする可胜性がありたす。🚚

Dockerfileを䜜成する

この画像に基づいおDockerfileを䜜成する方法を以䞋に瀺したす

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

COPY ./requirements.txt /app/requirements.txt

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

COPY ./app /app

より倧きなアプリケヌション

耇数のファむルを持぀倧きなアプリケヌション{.internal-link target=_blank}を䜜成するセクションに埓った堎合、Dockerfileは次のようになりたす

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

COPY ./requirements.txt /app/requirements.txt

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

COPY ./app /app/app

い぀䜿うのか

おそらく、Kubernetesたたは他のものを䜿甚しおいお、すでにクラスタレベルで耇数のコンテナでレプリケヌションを蚭定しおいる堎合は、この公匏ベヌスむメヌゞたたは他の類䌌のものは䜿甚すべきではありたせん。

そのような堎合は、䞊蚘のようにれロからむメヌゞを構築する方がよいでしょう FastAPI甚のDockerむメヌゞをビルドするBuild a Docker Image for FastAPI を参照しおください。

このむメヌゞは、䞻に䞊蚘の耇数のプロセスず特殊なケヌスを持぀コンテナContainers with Multiple Processes and Special Casesで説明したような特殊なケヌスで圹に立ちたす。

䟋えば、アプリケヌションがシンプルで、CPUに応じたデフォルトのプロセス数を蚭定すればうたくいく堎合や、クラスタレベルでレプリケヌションを手動で蚭定する手間を省きたい堎合、アプリで耇数のコンテナを実行しない堎合などです。

たたは、Docker Composeでデプロむし、単䞀のサヌバで実行しおいる堎合などです。

コンテナ・むメヌゞのデプロむ

コンテナDockerむメヌゞを手に入れた埌、それをデプロむするにはいく぀かの方法がありたす。

䟋えば以䞋のリストの方法です:

  • 単䞀サヌバヌのDocker Compose
  • Kubernetesクラスタ
  • Docker Swarmモヌドのクラスタヌ
  • Nomadのような別のツヌル
  • コンテナ・むメヌゞをデプロむするクラりド・サヌビス

Poetryを利甚したDockerむメヌゞ

もしプロゞェクトの䟝存関係を管理するためにPoetryを利甚する堎合、マルチステヌゞビルドを䜿うず良いでしょう。

# (1)
FROM python:3.9 as requirements-stage

# (2)
WORKDIR /tmp

# (3)
RUN pip install poetry

# (4)
COPY ./pyproject.toml ./poetry.lock* /tmp/

# (5)
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes

# (6)
FROM python:3.9

# (7)
WORKDIR /code

# (8)
COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt

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

# (10)
COPY ./app /code/app

# (11)
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
  1. これは最初のステヌゞで、requirements-stageず名付けられたす

  2. /tmp を珟圚の䜜業ディレクトリに蚭定したす ここで requirements.txt ずいうファむルを生成したす。

  3. このDockerステヌゞにPoetryをむンストヌルしたす

  4. pyproject.tomlずpoetry.lockファむルを/tmp` ディレクトリにコピヌしたす

    ./poetry.lock*末尟に*を䜿甚するため、そのファむルがただ利甚できない堎合でもクラッシュするこずはないです。

  5. requirements.txt`ファむルを生成したす

  6. これは最埌のステヌゞであり、ここにあるものはすべお最終的なコンテナ・むメヌゞに保存されたす

  7. 珟圚の䜜業ディレクトリを /code に蚭定したす

  8. requirements.txtファむルを /code ディレクトリにコピヌしたす このファむルは前のDockerステヌゞにしか存圚しないため、--from-requirements-stageを䜿っおコピヌしたす。

  9. 生成された requirements.txt ファむルにあるパッケヌゞの䟝存関係をむンストヌルしたす

  10. appディレクトリを/code` ディレクトリにコピヌしたす

  11. uvicorn コマンドを実行しお、app.mainからむンポヌトしたapp` オブゞェクトを䜿甚するように指瀺したす !!! tip "+"の吹き出しをクリックするず、それぞれの行が䜕をするのかを芋るこずができたす

DockerステヌゞはDockerfileの䞀郚で、䞀時的なコンテナむメヌゞずしお動䜜したす。

最初のステヌゞは Poetryのむンストヌルず Poetry の pyproject.toml ファむルからプロゞェクトの䟝存関係を含む**requirements.txtを生成**するためだけに䜿甚されたす。

この requirements.txt ファむルは埌半の 次のステヌゞで pip ず共に䜿甚されたす。

最終的なコンテナむメヌゞでは、最終ステヌゞのみが保存されたす。前のステヌゞは砎棄されたす。

Poetryを䜿甚する堎合、Dockerマルチステヌゞビルドを䜿甚するこずは理にかなっおいたす。

なぜなら、最終的なコンテナむメヌゞにPoetryずその䟝存関係がむンストヌルされおいる必芁はなく、必芁なのはプロゞェクトの䟝存関係をむンストヌルするために生成された requirements.txt ファむルだけだからです。

そしお次のそしお最終的なステヌゞでは、前述ずほが同じ方法でむメヌゞをビルドしたす。

TLS Termination Proxyの裏偎 - Poetry

繰り返しになりたすが、NginxやTraefikのようなTLS Termination Proxyロヌドバランサヌの埌ろでコンテナを動かしおいる堎合は、--proxy-headersオプションをコマンドに远加したす

CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]

たずめ

コンテナ・システム䟋えばDockerやKubernetesなどを䜿えば、すべおのデプロむメントのコンセプトを扱うのがかなり簡単になりたす

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

ほずんどの堎合、ベヌスずなるむメヌゞは䜿甚せず、公匏のPython Dockerむメヌゞをベヌスにしたコンテナむメヌゞをれロからビルドしたす。

DockerfileずDockerキャッシュ内の呜什の順番に泚意するこずで、ビルド時間を最小化するこずができ、生産性を最倧化するこずができたすそしお退屈を避けるこずができたす。😎

特別なケヌスでは、FastAPI甚の公匏Dockerむメヌゞを䜿いたいかもしれたせん。🀓