Dockerネットワーク入門
Dockerで複数のコンテナを利用する場合、コンテナ間の通信を理解することが重要です。特に、Docker Composeを使用してNginx、FastAPI、PostgreSQLなどを構成する場合、各コンテナがどのように通信するのかを理解しておく必要があります。
本記事では、Dockerネットワークの基本概念から、Docker Composeでのコンテナ間通信、portsとexposeの違いまでを解説します。
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がネットワークを作成し、apiとdbのコンテナを同じネットワークに接続します。
そのため、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
と指定した場合、localhostはPostgreSQLコンテナではなく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. portsとexposeの違い
Docker Composeでは、portsとexposeを混同しやすいため注意が必要です。
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のような複数コンテナ構成をより正しく設計できるようになります。