はじめに
この記事は、Docker Composeの基本的な使い方を理解している方を対象に、コンテナ間のネットワーク設定について解説します。
この記事で学べること
- Docker Composeにおけるネットワークの基本概念
- カスタムネットワークの定義方法
- 実践的なネットワーク構成パターン
- ネットワーク設定の詳細オプション
複数のコンテナを連携させるアプリケーション開発では、適切なネットワーク設計が重要です。この記事を通じて、セキュリティを考慮した効率的なネットワーク構成を実現できるようになりましょう。
Docker Composeのネットワーク基礎
デフォルトネットワークの動作
Docker Composeは、docker-compose.ymlファイルを実行すると自動的にネットワークを作成します。
version: '3.8'
services:
web:
image: nginx:latest
db:
image: postgres:latest
上記の設定を実行すると、プロジェクト名_defaultという名前のネットワークが自動生成されます。このネットワーク内では、各サービスはサービス名を使って相互に通信できます。
例えば、webコンテナからdbコンテナへはdb:5432という形式でアクセス可能です。これはDocker Composeが内蔵DNSによる名前解決を提供しているためです。
ネットワークが必要になる場面
カスタムネットワークを定義する主な理由は以下の通りです。
複数サービスのグループ化
関連するサービスを同じネットワークに配置し、他のサービスから分離できます。
セキュリティの向上
データベースなど機密性の高いサービスを、フロントエンドから直接アクセスできないネットワークに配置することで、セキュリティを強化できます。
マイクロサービスアーキテクチャ
サービスごとに異なるネットワークを割り当て、通信経路を明示的に制御できます。
カスタムネットワークの定義方法
基本的な書き方
カスタムネットワークはnetworksセクションで定義し、各サービスに割り当てます。
version: '3.8'
services:
web:
image: nginx:latest
networks:
- frontend
app:
image: myapp:latest
networks:
- frontend
- backend
db:
image: postgres:latest
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
この構成では以下のような通信が可能です。
appサービスは両方のネットワークに所属しているため、webとdbの両方と通信できます。一方、webとdbは直接通信できません。
ネットワークドライバーの種類
Docker Composeでは複数のネットワークドライバーが利用できます。
bridge(デフォルト)
同一ホスト上のコンテナ間通信に使用する最も一般的なドライバーです。独立したネットワーク空間を作成し、コンテナ間を接続します。
networks:
mynetwork:
driver: bridge
host
コンテナがホストのネットワークスタックを直接使用します。ネットワークの分離がなくなりますが、パフォーマンスが向上する場合があります。
services:
app:
image: myapp:latest
network_mode: host
overlay
Docker Swarmモードで複数ホスト間のコンテナ通信に使用します。通常のDocker Composeではあまり使用しません。
networks:
mynetwork:
driver: overlay
使い分けのポイント
- 開発環境やシングルホスト構成:
bridge - 高パフォーマンスが必要な特定サービス:
host - 複数ホスト構成(Swarmモード):
overlay
実践的な構成例
シンプルな2層構成
WebサーバーとDBサーバーを接続する基本的な構成です。
version: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
networks:
- app-network
postgres:
image: postgres:14
environment:
POSTGRES_PASSWORD: example
networks:
- app-network
networks:
app-network:
driver: bridge
この構成では、nginxコンテナからpostgres:5432でデータベースにアクセスできます。
3層アーキテクチャ
フロントエンド、バックエンド、データベースを分離した構成です。
version: '3.8'
services:
frontend:
image: react-app:latest
ports:
- "3000:3000"
networks:
- frontend-network
backend:
image: api-server:latest
networks:
- frontend-network
- backend-network
database:
image: postgres:14
environment:
POSTGRES_PASSWORD: example
networks:
- backend-network
networks:
frontend-network:
driver: bridge
backend-network:
driver: bridge
この構成により、フロントエンドから直接データベースへアクセスすることを防ぎ、セキュリティを強化しています。
マイクロサービス構成
複数のサービスを適切なネットワークで分離する例です。
version: '3.8'
services:
api-gateway:
image: gateway:latest
ports:
- "8080:8080"
networks:
- public
- service-network
user-service:
image: user-service:latest
networks:
- service-network
- database-network
order-service:
image: order-service:latest
networks:
- service-network
- database-network
user-db:
image: postgres:14
environment:
POSTGRES_DB: users
POSTGRES_PASSWORD: example
networks:
- database-network
order-db:
image: postgres:14
environment:
POSTGRES_DB: orders
POSTGRES_PASSWORD: example
networks:
- database-network
networks:
public:
driver: bridge
service-network:
driver: bridge
database-network:
driver: bridge
この構成では、データベースへのアクセスは各サービスからのみ可能で、APIゲートウェイから直接接続できません。
ネットワーク設定のオプション
IPアドレスの固定
特定のコンテナに固定IPアドレスを割り当てることができます。
version: '3.8'
services:
web:
image: nginx:latest
networks:
custom-network:
ipv4_address: 172.20.0.10
db:
image: postgres:14
networks:
custom-network:
ipv4_address: 172.20.0.20
networks:
custom-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
**ipam(IP Address Management)**はネットワークのIPアドレス範囲とゲートウェイを定義します。固定IPを使用する場合は、サブネットの設定が必須です。
注意点
固定IPアドレスは、コンテナのポータビリティを低下させる可能性があります。サービス名による名前解決で十分な場合は、固定IPの使用を避けましょう。
外部ネットワークの利用
既存のDockerネットワークに接続する場合は、external: trueを使用します。
version: '3.8'
services:
app:
image: myapp:latest
networks:
- existing-network
networks:
existing-network:
external: true
この設定は、別のDocker Composeプロジェクトやdocker network createコマンドで作成したネットワークを共有する際に便利です。
事前にネットワークを作成しておく必要があります。
docker network create existing-network
docker-compose up
ネットワークエイリアス
1つのサービスに複数の名前でアクセスできるようにする機能です。
version: '3.8'
services:
database:
image: postgres:14
networks:
backend:
aliases:
- db
- postgres
- primary-db
networks:
backend:
driver: bridge
この設定により、database、db、postgres、primary-dbのいずれの名前でもこのサービスにアクセスできます。複数のアプリケーションが異なる名前でデータベースを参照している場合に便利ですね。
トラブルシューティング
よくある問題と解決方法
ネットワークに接続できない
症状:コンテナ間で通信ができない
確認ポイント
- サービスが同じネットワークに所属しているか確認
- サービス名のスペルミスがないか確認
- ファイアウォールやセキュリティグループの設定
# ネットワークの確認
docker network ls
# コンテナのネットワーク接続状況を確認
docker network inspect プロジェクト名_ネットワーク名
名前解決ができない
症状:サービス名でアクセスできない
解決方法
- デフォルトネットワークではなく、カスタムネットワークを使用しているか確認
- サービス名が正しいか確認(ハイフンやアンダースコアの違いに注意)
# 正しい例
services:
my-service:
networks:
- mynetwork
# 別のサービスからは my-service:ポート番号 でアクセス
ポートの競合
症状:コンテナの起動時にポートバインディングエラーが発生
解決方法
- ホスト側のポート番号を変更
- 既に使用されているコンテナやプロセスを停止
services:
web:
image: nginx:latest
ports:
- "8080:80" # ホスト側のポートを80から8080に変更
# ポート使用状況の確認
netstat -an | grep LISTEN
# または
lsof -i :80
ネットワークが削除できない
症状:docker network rmでエラーが発生
解決方法
- ネットワークを使用しているコンテナをすべて停止・削除
- Docker Composeで管理している場合は
docker-compose downを実行
# コンテナをすべて停止・削除
docker-compose down
# ネットワークを削除
docker network rm ネットワーク名
まとめ
Docker Composeのネットワーク設定について解説しました。重要なポイントを振り返りましょう。
基本原則
- デフォルトネットワークは自動作成され、サービス名で通信可能
- カスタムネットワークで通信経路を制御し、セキュリティを向上
- 複数のネットワークを組み合わせて階層化されたアーキテクチャを実現
ベストプラクティス
- データベースなど機密性の高いサービスは専用ネットワークに配置
- サービス名による名前解決を活用し、固定IPの使用は最小限に
- ネットワーク名は用途が分かりやすい名前を付ける
- 外部公開するサービスと内部サービスを明確に分離
適切なネットワーク設計により、セキュアで保守性の高いコンテナアプリケーションを構築できます。実際のプロジェクトで試してみてください。