Dockerコンテナのデータベース接続

Dockerで動作するデータベースへの接続文字列の構築。ホスト→コンテナ、コンテナ→コンテナ、docker-composeネットワーキング、ポートマッピングを解説します。

Best Practices

詳細な説明

Dockerデータベースネットワーキング

Dockerコンテナでデータベースを実行する場合、接続文字列はクライアントがコンテナに対してどこで実行されているかによって異なります。

シナリオ1:ホストからコンテナへ

アプリがホストマシンで動作し、データベースが公開ポートを持つコンテナで動作:

# docker-compose.yml
services:
  postgres:
    image: postgres:16
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb

ホストからの接続文字列:

postgresql://myuser:secret@localhost:5432/mydb

重要なのはlocalhost公開ポート(portsマッピングの左側)を使用することです。

シナリオ2:コンテナからコンテナ(同じネットワーク)

アプリとデータベースの両方が同じネットワーク上のDockerで実行:

services:
  app:
    build: .
    depends_on:
      - postgres
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb

appコンテナからの接続文字列:

postgresql://myuser:secret@postgres:5432/mydb

ホストとしてサービス名postgres)を使用します。Docker Composeは各サービスのDNSエントリを作成します。コンテナポート(portsマッピングの右側、またはポートが公開されていない場合はデフォルト)を使用します。

シナリオ3:カスタムネットワーク

docker network create mynet
docker run -d --name mydb --network mynet -e POSTGRES_PASSWORD=secret postgres:16
docker run -d --name myapp --network mynet myapp-image

myappからの接続文字列:

postgresql://postgres:secret@mydb:5432/postgres

よくある落とし穴

  1. コンテナ内でのlocalhostの使用 — コンテナ内ではlocalhostはホストではなくコンテナ自体を指します。代わりにサービス名またはコンテナ名を使用してください。

  2. ポートの混乱 — 公開ポートはホストアクセス用です。同じネットワーク上のコンテナは内部ポート(例:PostgreSQLの5432、マッピングされたポートではない)を使用します。

  3. 準備完了の待機 — ヘルスチェック付きのdepends_onを使用して、アプリが接続を試みる前にデータベースが準備完了していることを確認してください:

services:
  postgres:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U myuser"]
      interval: 5s
      timeout: 5s
      retries: 5
  app:
    depends_on:
      postgres:
        condition: service_healthy

ユースケース

Docker Composeを使ったローカル開発環境の構築、コンテナ化されたデータベースに対する統合テストの実行、共有Dockerネットワーク上のデータベースコンテナと通信するマイクロサービスの設定。

試してみる — Connection String Builder

フルツールを開く