たねやつの木

Photographs, Keyboards and Programming

【Dockerを知る:第6回】 Docker ComposeでWeb APIとDBを連携させる

こんにちは、たねやつです。

前回はDocker Composeを使って、単一のAPIコンテナをスマートに管理する方法を学びました。 今回は、Docker Composeの最も強力な機能の一つである、複数コンテナの連携に挑戦します。前回作成したFastAPIアプリケーションに、永続的なデータを保存するためのデータベース(PostgreSQL)コンテナを連携させてみましょう。

前の記事

www.taneyats.com

この記事でできること

  • 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で定義されたサービス(appdb)を、自動的にdefaultという名前の仮想ネットワークに接続します。 そして、そのネットワーク内では、サービス名がそのままホスト名として使えます

つまり、appコンテナの中から、dbというホスト名でdbコンテナ(PostgreSQL)にアクセスできるのです。 (例: データベース接続文字列は postgresql://user:password@db:5432/mydatabase のようになります)

複数コンテナの起動

それでは、更新したdocker-compose.ymlを使ってアプリケーション全体を起動してみましょう。

docker compose up -d

docker psコマンドを実行すると、appdbの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というコンテナオーケストレーションの世界に入っていきます。

次の記事

www.taneyats.com