このレッスンのロックを解除するには、まず「プロトタイプから本番環境へ:デプロイメント・マインドセット」を完了してください。前のレッスンに戻る

はじめに

ノートPCでAI生成ウェブアプリをビルドすると、Pythonがインストールされていて、依存関係が正しい場所にあり、環境変数がちょうど適切に設定されているため、動作します。そのアプリをサーバーやチームメンバーのマシン、クラウドプラットフォームに移行すると、突然何も動かなくなります。Dockerは、アプリケーションとそれが必要とするすべてをコンテナと呼ばれる単一の移植可能なユニットにパッケージ化することで、この問題を解決します。

このレッスンでは、典型的なPythonウェブアプリ用のDockerfileを作成し、それをイメージにビルドし、アプリが依存するサービス(データベースやRedisなど)と一緒にアプリを実行するためにDocker Composeを使用します。焦点は実践的です。終わりまでに、自信を持ってAI生成ウェブアプリをコンテナ化できるようになることが目標です。

初めてのDockerfileを書く

Dockerfileは、Dockerがイメージを構築するために読み取る命令が書かれたテキストファイルです。レシピと考えてください:各行がレイヤーを追加します。AI生成ウェブアプリの場合、最も一般的なセットアップは、Uvicornによって配信されるFastAPIまたはFlaskアプリです。

以下是Pythonウェブアプリ用の最小限のDockerfileです:

dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

各行を分解して説明します。`FROM python:3.11-slim`は公式の軽量Pythonイメージから開始します。`WORKDIR /app`はコンテナ内の作業ディレクトリを設定し、後続のコマンドがそこで実行されるようにします。`COPY requirements.txt .`はまず依存関係ファイルのみをコピーします。これによりDockerは`pip install`ステップをキャッシュでき、コードのみを変更したときにはそれをスキップできます。次に`COPY . .`でソースコードをコピーします。`EXPOSE 8000`はアプリがリッスンするポートを文書化します。`CMD`はコンテナ起動時に実行されるコマンドを定義します。

よくある間違いは、依存関係をインストールする前にすべてをコピーしてしまうことです。これを行うと、Pythonファイルを1つだけ変更するたびに、Dockerは重い`pip install`レイヤーを毎回再ビルドせざるを得なくなります。速度にとって順序は重要です。

上記のDockerfileをビルドしたときのDockerイメージのレイヤー構成図。ベースイメージのpython:3.11-slimからアプリケーションコードまで

イメージのビルドと実行

Dockerfileが用意できたら、2つのコマンドで実行中のコンテナに変換します。まず、イメージをビルドして名前を付けてタグ付けします:

bash
docker build -t my-ai-app:1.0 .

`.`はDockerにDockerfileの場所を伝えます(現在のディレクトリ)。`-t`フラグは名前とバージョンタグを割り当て、後でイメージを参照しやすくします。次に実行します:

bash
docker run -p 8000:8000 my-ai-app:1.0

`-p 8000:8000`フラグは、ホストのポート8000をコンテナ内のポート8000にマッピングします。これがないと、アプリは実行されますがブラウザからアクセスできません。`http://localhost:8000`にアクセスすると、アプリが応答しているのが確認できるはずです。

イメージが正しくビルドされたか確認するには、すべてのイメージを一覧表示します:

bash
docker images

実行中のコンテナを確認するには、`docker ps`を使用します。停止中のコンテナも含めるには`-a`を追加します。

マルチサービスアプリにDocker Composeを使用する

ほとんどのAIウェブアプリは単独では動作しません。通常、データベース(PostgreSQL)、キャッシュ(Redis)、またはその両方が必要です。それぞれを個別の`docker run`コマンドで管理すると、すぐに煩雑になります。Docker Composeを使用すると、すべてのサービスを1つのYAMLファイルで宣言し、一緒に起動できます。

`docker-compose.yml`という名前のファイルを作成します:

yaml
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:16
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:

`web`サービスがホスト名で`db`を参照していることに注目してください。Docker Composeはプライベートネットワークを作成し、サービス同士がサービス名で互いに到達できるようにします。`depends_on`ディレクティブは、ウェブアプリより先にデータベースを起動するようDockerに指示します。名前付きボリューム`pgdata`は、コンテナが削除されてもデータベースデータを安全に保持します。

すべてを起動するには:

bash
docker compose up --build

バックグラウンドで実行するには`-d`を追加します。コンテナを停止して削除するには:

bash
docker compose down

よくある間違いとその回避方法

.dockerignoreファイルの忘れは頻繁に見られる見落としです。Dockerfileと同じ場所に作成してください:

bash
echo -e "__pycache__\n.git\n.env\n*.pyc" > .dockerignore

これがないと、イメージに不要なファイルが含まれ、ビルドが遅くなり、APIキーを含む`.env`ファイルなどのシークレットが漏洩するリスクがあります。

もう一つの落とし穴は、シークレットをイメージ内にハードコーディングすることです。APIキーやデータベースパスワードをDockerfileに直接記述しないでください。代わりに環境変数を使用するか、ランタイムでシークレットファイルをマウントしてください。

最後に、デフォルトでrootとしてコンテナを実行することは本番環境ではセキュリティリスクです。本格的にデプロイする準備ができたら、Dockerfileに非rootユーザーを追加してください。

まとめ

Dockerfileは、アプリをイメージにパッケージ化する方法を記述します。Docker Composeは、単一のYAMLファイルを通じて複数のコンテナをまとめてオーケストレーションします。AI生成ウェブアプリの場合、一般的なワークフローは次のとおりです:依存関係を最初にコピーするDockerfileを書き、`docker build`でイメージをビルドし、`docker run -p`で実行し、データベースなどのサービスを追加するときにComposeに拡張する。これらの4つのコマンドと1つのYAML構造をマスターすることで、あらゆるクラウドプラットフォームにデプロイ可能なコンテナ化アプリの90%までの道が開けます。

レッスンの練習

レッスンのチェックポイント

学んだ内容を復習し、回答へのフィードバックを受けましょう。

0/1
回答済み · 0/1
Dockerでアプリケーションをコンテナ化する