Dockerネットワーク入門

Dockerで複数のコンテナを利用する場合、コンテナ間の通信を理解することが重要です。特に、Docker Composeを使用してNginx、FastAPI、PostgreSQLなどを構成する場合、各コンテナがどのように通信するのかを理解しておく必要があります。

本記事では、Dockerネットワークの基本概念から、Docker Composeでのコンテナ間通信、portsexposeの違いまでを解説します。

1. Dockerネットワークとは

Dockerネットワークは、Dockerコンテナ同士、またはコンテナとホスト・外部ネットワークとの通信を管理する仕組みです。

例えば、以下のようなシステムを考えます。

ブラウザ
 Nginx
 FastAPI
PostgreSQL

それぞれをDockerコンテナとして実行する場合、

  • Nginxコンテナ
  • FastAPIコンテナ
  • PostgreSQLコンテナ

の3つが存在します。

このとき、FastAPIからPostgreSQLへ接続するためのネットワークが必要になります。

Dockerでは、このようなコンテナ間通信をDockerネットワークによって実現します。


2. Dockerのデフォルトネットワーク

Dockerをインストールすると、いくつかのネットワークが作成されています。

docker network ls

例えば以下のような結果になります。

NETWORK ID     NAME      DRIVER    SCOPE
xxxxxx         bridge    bridge    local
xxxxxx         host      host      local
xxxxxx         none      null      local

代表的なネットワークには以下があります。

ネットワーク説明
bridge一般的なコンテナネットワーク
hostホストのネットワークを直接利用
noneネットワーク通信を無効化

通常のWebアプリケーションでは、bridge系のネットワークを利用するケースが多くなります。


3. Docker Composeではネットワークが自動作成される

Docker Composeを使用すると、通常はComposeプロジェクト用のネットワークが自動的に作成されます。

例えば、以下のcompose.yamlを作成します。

services:
  api:
    image: my-api

  db:
    image: postgres:16

以下を実行します。

docker compose up -d

この場合、Docker Composeがネットワークを作成し、apidbのコンテナを同じネットワークに接続します。

そのため、apiコンテナからdbコンテナへ通信できます。


4. コンテナ間通信ではサービス名を使用する

Dockerネットワークで特に重要なのが、サービス名による通信です。

例えばPostgreSQLのサービス名をdbとします。

services:
  api:
    image: my-api

  db:
    image: postgres:16

FastAPIからPostgreSQLへ接続する場合、

localhost:5432

ではなく、

db:5432

を使用します。

つまり、

DATABASE_HOST=db
DATABASE_PORT=5432

のようになります。

Docker Composeではサービス名がDockerネットワーク内のホスト名として利用できます。

localhostに注意

例えばFastAPIコンテナ内で、

localhost:5432

と指定した場合、localhostPostgreSQLコンテナではなくFastAPIコンテナ自身を意味します。

これはDockerを使い始めたときに非常に間違いやすいポイントです。

FastAPIコンテナ
    ├─ localhost
    │      ↓
    │   FastAPI自身
    └─ db:5432
       PostgreSQL

5. portsとは

portsは、コンテナのポートをホスト側へ公開するために使用します。

例えば、

services:
  nginx:
    image: nginx
    ports:
      - "8080:80"

の場合、

ホストPC:8080
コンテナ:80

という通信になります。

ブラウザから、

http://localhost:8080

へアクセスすると、Nginxコンテナの80番ポートへ接続されます。


6. PostgreSQLの5432番ポートを公開する必要はあるのか

例えば、

services:
  api:
    image: my-api

  db:
    image: postgres:16

という構成の場合、FastAPIからPostgreSQLへ接続するだけなら、PostgreSQLの5432番ポートをホストへ公開する必要はありません。

つまり、以下は必須ではありません。

ports:
  - "5432:5432"

FastAPIから、

db:5432

へ接続できれば通信できます。

構成としては、

インターネット
   Nginx
  :8080
   FastAPI
 PostgreSQL
   :5432

とすることができます。

この場合、PostgreSQLは外部から直接アクセスできないため、不要なポート公開を減らせます。


7. portsexposeの違い

Docker Composeでは、portsexposeを混同しやすいため注意が必要です。

ports

ports:
  - "8080:80"

ホスト側へポートを公開します。

ホスト → コンテナ

の通信を可能にします。

expose

expose:
  - "8000"

コンテナ間通信で使用するポートを明示できますが、ホストへポートを公開するものではありません。

例えば、

services:
  api:
    image: my-api
    expose:
      - "8000"

  db:
    image: postgres:16

という構成にできます。

ただし、Composeの同一ネットワーク内では通常、サービス間通信が可能なため、単純な構成ではexposeを必ず記述する必要はありません。


8. ネットワークを確認する

現在作成されているDockerネットワークは、

docker network ls

で確認できます。

ネットワークの詳細は、

docker network inspect <ネットワーク名>

で確認できます。

例えば、

docker network inspect myproject_default

とすると、そのネットワークに接続されているコンテナなどを確認できます。

トラブルシューティングでは非常に便利なコマンドです。


9. 実際の3コンテナ構成

Nginx、FastAPI、PostgreSQLをDocker Composeで構成すると、例えば以下のようになります。

services:
  nginx:
    image: nginx:latest
    ports:
      - "8080:80"
    depends_on:
      - api

  api:
    image: my-fastapi
    expose:
      - "8000"
    depends_on:
      - db

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: sample
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

通信関係は以下のようになります。

ブラウザ
   │ localhost:8080
┌─────────────┐
│    Nginx    │
│    :80      │
└──────┬──────┘
       │ api:8000
┌─────────────┐
│   FastAPI   │
│   :8000     │
└──────┬──────┘
       │ db:5432
┌─────────────┐
│ PostgreSQL  │
│   :5432     │
└─────────────┘

ここで重要なのは、ホスト側のポートとコンテナ内部のポートは別物という点です。

例えば、

ports:
  - "8080:80"

なら、

ホスト → 8080
コンテナ → 80

です。

一方、コンテナ間通信では、

api:8000
db:5432

のようにサービス名を使用します。


10. Dockerネットワークで注意するポイント

Dockerネットワークでは、以下の点を特に意識する必要があります。

localhostの意味

コンテナ内のlocalhostは、そのコンテナ自身です。

別コンテナへ接続する場合はサービス名を使用します。

db:5432

② 必要以上にポートを公開しない

PostgreSQLをFastAPIだけが使用するのであれば、

ports:
  - "5432:5432"

を設定する必要はありません。

外部公開が必要なサービスだけportsを設定する構成が基本です。


③ コンテナIPを直接指定しない

コンテナにはIPアドレスが割り当てられますが、コンテナの再作成などによってIPが変わる可能性があります。

そのため、

172.x.x.x

のようなコンテナIPをアプリケーションに直接設定するのではなく、

db
api
nginx

のようなサービス名を使用する方が適切です。


まとめ

Dockerネットワークは、複数コンテナでアプリケーションを構築する際の基本的な仕組みです。

特にDocker Composeでは、サービスごとにコンテナを分離しながら、同じネットワーク上で通信できます。

重要なポイントを整理すると、以下のようになります。

  • DockerコンテナはDockerネットワークを介して通信する
  • Docker Composeではネットワークが基本的に自動作成される
  • コンテナ間通信ではサービス名を使用する
  • localhostは接続先コンテナを意味しない
  • portsはホストへポートを公開するために使用する
  • PostgreSQLなど内部通信だけで使用するサービスは、必ずしもportsを公開する必要はない
  • コンテナIPを直接指定せず、サービス名を使用する

Dockerのネットワークを理解すると、Nginx → FastAPI → PostgreSQLのような複数コンテナ構成をより正しく設計できるようになります。