こんにちは、たねやつです。
前回はDocker Composeを使って、単一のAPIコンテナをスマートに管理する方法を学びました。 今回は、Docker Composeの最も強力な機能の一つである、複数コンテナの連携に挑戦します。前回作成したFastAPIアプリケーションに、永続的なデータを保存するためのデータベース(PostgreSQL)コンテナを連携させてみましょう。
前の記事
この記事でできること
docker-compose.ymlに複数のサービス(コンテナ)を定義できる。- Docker Composeのネットワーク機能を使い、コンテナ間でサービス名による通信ができることを理解する。
- Docker Volumeを使い、コンテナが削除されてもデータを永続化する方法を理解する。
事前に必要なもの
- 前回作成したFastAPIアプリケーションと
docker-compose.yml
docker-compose.ymlの更新
まず、docker-compose.ymlにPostgreSQLのサービス定義を追加します。
version: "3.9" services: app: build: . ports: - "8000:80" volumes: - .:/app # ★追加: DBコンテナが起動してからappコンテナが起動するようにする depends_on: - db db: image: postgres:14-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=password - POSTGRES_DB=mydatabase volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" # ★追加: 名前付きボリュームの定義 volumes: postgres_data:
変更点・追加点を詳しく見ていきましょう。
dbサービスの定義
image: postgres:14-alpine:dbサービスでは、Dockerfileからビルドする代わりに、Docker Hubにある公式のpostgresイメージを直接指定しています。14-alpineは、バージョン14の軽量版です。environment:: コンテナ内で使用する環境変数を設定します。PostgreSQLイメージでは、これらの環境変数を使って初期ユーザーやデータベースを自動で作成してくれます。POSTGRES_USER: データベースのユーザー名POSTGRES_PASSWORD: ユーザーのパスワードPOSTGRES_DB: 作成するデータベース名
volumes: - postgres_data:/var/lib/postgresql/data: 名前付きボリュームpostgres_dataを、PostgreSQLがデータを保存するコンテナ内のディレクトリ/var/lib/postgresql/dataにマウントしています。ports: - "5432:5432": ホストマシンから直接DBに接続して中身を確認したい場合のために、PostgreSQLのデフォルトポートである5432をフォワーディングしています。(開発時に便利です)
appサービスの変更
depends_on: - db: サービスの起動順序を制御します。これにより、Docker Composeはdbコンテナが起動し準備が整うのを待ってから、appコンテナを起動するようになります。アプリケーションが起動時にDB接続を試みる場合などに必須の設定です。
トップレベルのvolumes定義
volumes: postgres_data::dbサービスで使った名前付きボリュームpostgres_dataをここで定義しています。名前付きボリュームはDockerによって管理され、docker compose downを実行しても自動的には削除されません。これにより、コンテナを再作成してもデータベースのデータが消えずに永続化されるわけです。
アプリケーションからDBに接続する(今回は接続確認のみ)
本来であれば、FastAPIアプリケーションのコードを修正して、実際にPostgreSQLに接続する処理を記述します。 しかし、今回はまず「コンテナ間通信」の概念を理解することに焦点を当てます。
Docker Composeは、docker-compose.ymlで定義されたサービス(appとdb)を、自動的にdefaultという名前の仮想ネットワークに接続します。
そして、そのネットワーク内では、サービス名がそのままホスト名として使えます。
つまり、appコンテナの中から、dbというホスト名でdbコンテナ(PostgreSQL)にアクセスできるのです。
(例: データベース接続文字列は postgresql://user:password@db:5432/mydatabase のようになります)
複数コンテナの起動
それでは、更新したdocker-compose.ymlを使ってアプリケーション全体を起動してみましょう。
docker compose up -d
docker psコマンドを実行すると、appとdbの2つのコンテナが起動していることが確認できます。
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fac6efe16474 postgres:14-alpine "docker-entrypoint.s…" 19 seconds ago Up 18 seconds 0.0.0.0:15432->5432/tcp, [::]:15432->5432/tcp fastapi-handson-db-1 2135e49dea27 fastapi-handson-app "uvicorn main:app --…" 58 seconds ago Up 18 seconds 0.0.0.0:8000->80/tcp, [::]:8000->80/tcp fastapi-handson-app-1
これで、APIサーバーとデータベースが連携して動作する、より実践的なアプリケーションの雛形が完成しました。
最後に
お疲れ様でした!今回は、Docker Composeを使ってWeb APIとデータベースという2つのコンテナを連携させる方法を学びました。
docker-compose.ymlに複数のサービスを定義できることdepends_onで起動順序を制御できること- サービス名を使ってコンテナ間で通信できること
- 名前付きボリュームでデータを永続化できること
これらの概念は、コンテナを使ったアプリケーション開発において非常に重要です。 来週からは、いよいよこのコンテナ技術の土台の上に、Kubernetesというコンテナオーケストレーションの世界に入っていきます。