Docker 環境で Python FastAPI Webサービスを起動する
こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu の Docker 環境で、Python FastAPI Web アプリケーションをコンテナーとして起動する方法を紹介します。
目的
Windows 11 の Linux でクラウド開発します。
こちらから記事の一覧がご覧いただけます。
実現すること
ローカル環境の WSL Ubuntu の Docker 環境で、Dockerfile からビルドした Python FastAPI Web サービスのカスタムコンテナーイメージを起動します。
Python ファイルのアプリをコンテナーとして起動
実行環境
要素 | 概要 |
---|---|
terminal | ターミナル |
Ubuntu | OS |
Docker | コンテナー実行環境 |
Web サービス コンテナー
要素 | 概要 |
---|---|
app-hello-fastapi | カスタムコンテナー |
python | Python 実行環境 |
main.py | Python スクリプト |
uvicorn | Web サーバー |
技術トピック
FastAPI とは?
こちらを展開してご覧いただけます。
FastAPI
FastAPI は、Python の Web フレームワークの中でもとくに注目されている新しいフレームワークであり、多くの特徴とメリットがあります。
キーワード | 内容 |
---|---|
高速な性能 | FastAPI は非常に高速なWebフレームワークであり、ASGI (Asynchronous Server Gateway Interface) を活用することで高いパフォーマンスを提供します。非同期処理をサポートすることで、同時リクエストの処理が可能となります。 |
シンプルで直感的な記述 | FastAPI はシンプルで直感的な構文を持ち、少ないコードで強力な API を構築できます。Python の型ヒント (Type Hints) を活用して、入力の検証やドキュメントの自動生成が行えます。 |
自動生成されたドキュメント | FastAPI は Swagger UI や Redoc を使って API のドキュメントを自動生成します。API エンドポイント、リクエストボディ、レスポンスなどが自動的にドキュメント化され、API の理解やテストが容易になります。 |
入力検証とシリアライゼーション | FastAPI はリクエストの入力データを自動的に検証し、Pydantic を使って型情報をシリアライズします。入力データのバリデーションエラーを自動的に処理できます。 |
依存性注入 | FastAPI は依存性注入をサポートしており、依存関係の注入によってコードの再利用性とテスト容易性が向上します。依存性注入を活用することで、アプリケーションの部品を疎結合に保ちながら効果的に結合できます。 |
サポートされるデータベースと ORM | FastAPI はさまざまなデータベースと ORM (Object-Relational Mapping) をサポートしています。たとえば、SQLAlchemy、Tortoise ORM、MongoDB、Redis などが利用可能です。 |
セキュリティ | FastAPI は標準的なセキュリティ機能を提供しています。OAuth2.0 や API キーのサポート、HTTPS 対応など、セキュアな API の構築が可能です。 |
Dockerfile とは?
こちらを展開してご覧いただけます。
Dockerfile
Dockerfile は、Docker コンテナーを構築するためのテキストファイルです。Docker コンテナーはアプリケーションやサービスを実行するための環境を含む軽量でポータブルな仮想化ユニットです。
キーワード | 内容 |
---|---|
スクリプト形式 | Dockerfile はシンプルなスクリプト形式で記述されるため、コンテナーのビルドプロセスを自動化することが容易です。 |
レイヤー構造 | Docker イメージは Dockerfile の各命令が実行される際にレイヤーとして生成され、再利用やキャッシュが可能な構造となっています。 |
バージョン管理 | Dockerfile はテキストベースであるため、コードと同様にバージョン管理システムで管理しやすいです。 |
ポータビリティ | Dockerfile により、アプリケーションとその依存関係が1つのコンテナイメージにパッケージ化されるため、異なる環境間での移植性が高まります。 |
自動化と効率化 | Dockerfile を使用することで、アプリケーションのビルドや環境構築を自動化できます。これにより、手動での作業時間やヒューマンエラーが減り、開発・デプロイプロセスが効率的になります。 |
再現性 | Dockerfile はビルド手順を完全に定義するため、異なる環境で同じアプリケーションを再現できます。これにより、開発、テスト、本番環境間での一貫性が確保されます。 |
環境の分離 | Docker コンテナーはホストシステムから分離されるため、アプリケーションの依存関係やライブラリの衝突を回避し、より安全な環境で実行できます。 |
拡張性 | Dockerfile を使用することで、カスタムイメージを作成できます。このため、特定のニーズに合わせてカスタマイズされたコンテナイメージを容易に作成できます。 |
開発環境
- Windows 11 Home 23H2 を使用しています。
WSL の Ubuntu を操作しますので macOS の方も参考にして頂けます。
WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます
> wsl --version
WSL バージョン: 2.2.4.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.61
Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04 LTS
Release: 24.04
Codename: noble
Docker ※ こちらの関連記事からインストール方法をご確認いただけます
$ docker --version
Docker version 27.0.3, build 7d4bcd8
この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法をはじめて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
作成する Web アプリケーションの仕様
No | エンドポイント | HTTPメソッド | MIME タイプ |
---|---|---|---|
1 | /api/data | GET | application/json |
/api/data というエンドポイントに対して HTTP GET リクエストを送信すると、JSON データがレスポンスされるシンプルな Web サービスを実装します。
{"message":"Hello World!"}
Hello World を表示する手順
Python の確認
通常 Ubuntu 24.04 には、Python はプリインストールされています。
$ python3 --version
Python 3.12.3
プロジェクトの作成
プロジェクトフォルダーを作成します。
※ ~/tmp/hello-fastapi をプロジェクトフォルダーとします。
$ mkdir -p ~/tmp/hello-fastapi
$ cd ~/tmp/hello-fastapi
Python ファイルの作成
main.py Python ファイルを作成します。
$ mkdir -p app
$ vim app/main.py
ファイルの内容
from fastapi import FastAPI
app = FastAPI()
@app.get('/api/data')
async def get_data():
response = {
'message': 'Hello World!'
}
return response
型宣言を省略せずに記述したコード
from fastapi import FastAPI
app: FastAPI = FastAPI()
@app.get('/api/data')
async def get_data():
response: dict[str, str] = {
'message': 'Hello World!'
}
return response
pipx をインストールします。
$ sudo apt update
$ sudo apt install pipx
バージョンを確認します。
$ pipx --version
1.4.3
pipx ツールへの PATH を追加します。
$ pipx ensurepath
パッケージを仮想環境にインストールします。
$ pipx install uvicorn
仮想環境にパッケージを追加でインストールします。
$ pipx inject uvicorn fastapi
ローカルで実行します。
停止するときは ctrl + C を押します。
$ uvicorn app.main:app \
--host 0.0.0.0 --port 8000
別ターミナルから curl コマンドで確認します。
$ curl -v http://localhost:8000/api/data -w '\n'
出力
* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8000...
* connect to ::1 port 8000 from ::1 port 57270 failed: 接続を拒否されました
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000
> GET /api/data HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Sat, 10 Aug 2024 13:40:43 GMT
< server: uvicorn
< content-length: 26
< content-type: application/json
<
* Connection #0 to host localhost left intact
{"message":"Hello World!"}
ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することができました。
コンテナイメージをビルド
Dockerfile を作成します。
$ vim Dockerfile
ファイルの内容
# set up the container.
FROM python:3.12-slim
# set the working dir.
WORKDIR /app
# copy the app dir.
COPY app app
# install libraries.
RUN pip install --no-cache-dir fastapi uvicorn
# expose the port.
EXPOSE 8000
# command to run the app using uvicorn.
CMD ["uvicorn","app.main:app","--host","0.0.0.0","--port","8000"]
説明を開きます。
要素 | 説明 |
---|---|
FROM python:3.10-slim | ベースイメージとして、Python 3.10 の slim版イメージを使用します。 |
WORKDIR /app | コンテナー内での作業ディレクトリを /app に設定します。 |
COPY app app: | ホストマシンのカレントディレクトリにある app ディレクトリを、コンテナー内の /app ディレクトリにコピーします。 |
RUN pip install --no-cache-dir fastapi uvicorn | 必要な Python ライブラリをインストールします。fastapi と uvicorn は、FastAPI フレームワークと ASGI サーバーのライブラリです。--no-cache-dir フラグは、キャッシュを使用せずにライブラリをインストールすることを意味します。 |
EXPOSE 8000 | コンテナーがポート 8000 を公開することを宣言します。 |
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] | コンテナー内で実行されるデフォルトのコマンドを定義します。FastAPI アプリケーションを起動するために uvicorn コマンドが使用されます。app.main:app は、FastAPI アプリケーションインスタンスを指すものです。--host 0.0.0.0 は、すべてのネットワークインターフェイスからの接続を許可することを意味し、--port 8000 は uvicorn がリッスンするポート番号を指定します。 |
Docker デーモンを起動します。
$ sudo service docker start
Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。
コンテナイメージをビルドします。
$ docker build \
--no-cache \
--tag app-hello-fastapi:latest .
コンテナイメージを確認します。
$ docker images | grep app-hello-fastapi
app-hello-fastapi latest c31921620823 53 seconds ago 153MB
ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。
コンテナーを起動
ローカルでコンテナーを起動します。
※ コンテナーを停止するときは ctrl + C を押します。
$ docker run --rm \
--publish 8000:8000 \
--name app-local \
app-hello-fastapi:latest
ここまでの手順で、ローカル環境の Docker でアプリのカスタムコンテナーを起動することができました。
コンテナーの動作確認
別ターミナルから curl コマンドで確認します。
$ curl -v http://localhost:8000/api/data -w '\n'
出力
* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8000...
* Connected to localhost (::1) port 8000
> GET /api/data HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Sat, 10 Aug 2024 14:23:23 GMT
< server: uvicorn
< content-length: 26
< content-type: application/json
<
* Connection #0 to host localhost left intact
{"message":"Hello World!"}
ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することができました。
コンテナーの状態を確認してみます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a132ae388071 app-hello-fastapi:latest "uvicorn app.main:ap…" 22 seconds ago Up 21 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp app-local
コンテナーに接続
別ターミナルからコンテナーに接続します。
$ docker exec -it app-local /bin/sh
コンテナー接続後にディレクトリを確認します。
※ コンテナーから出るときは ctrl + D を押します。
# pwd
/app
# ls -lah
total 12K
drwxr-xr-x 1 root root 4.0K Aug 10 14:21 .
drwxr-xr-x 1 root root 4.0K Aug 10 14:24 ..
drwxr-xr-x 3 root root 4.0K Aug 10 13:26 app
top コマンドで状況を確認します。
# apt update
# apt install procps
# top
top - 14:26:44 up 2:11, 0 user, load average: 0.11, 0.07, 0.01
Tasks: 3 total, 1 running, 2 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.1 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15949.2 total, 14997.9 free, 825.5 used, 403.4 buff/cache
MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 15123.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 55068 48880 14176 S 0.3 0.3 0:00.75 uvicorn
7 root 20 0 2576 892 800 S 0.0 0.0 0:00.00 sh
175 root 20 0 8992 4732 2860 R 0.0 0.0 0:00.00 top
コンテナーの情報を表示してみます。
# cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
このコンテナーは Debian GNU/Linux をベースに作成されています。つまり、Debian GNU/Linux と同じように扱うことができます。
ディレクトリ・ファイル構成
プロジェクトのファイル構成を表示してみます。
$ tree -I '__pycache__'
.
├── Dockerfile
└── app
└── main.py
まとめ
WSL Ubuntu の Docker 環境で、Dockerfile からビルドした Python FastAPI Web サービスのカスタムコンテナーを起動することができました。
クラウド開発においては、Dockerfile の理解は重要です。自動ビルドツールもありますが、手動で書く必要があるケースもあります。Ubuntu を使うと Linux の知識も身に付きます。最初は難しく感じるかもしれませんが、徐々に進めていけば自信を持って書けるようになります。
どうでしたか? WSL Ubuntu で、Python FastAPI Web アプリケーションを手軽に実行できます。ぜひお試しください。今後も Python の開発環境などを紹介しますので、ぜひお楽しみにしてください。
推奨コンテンツ