はじめに
Docker Compose
でコンテナアプリケーションを構築する際、コンテナ間の通信やロードバランサーの設定で、特定のコンテナに固定IPアドレスを割り当てたい場合がある。
デフォルトでは、Docker Compose
はコンテナに172.17.0.0/16
のネットワークの範囲でIPアドレスを割り当てるため、コンテナの再起動のたびにIPアドレスが変更される可能性がある。
これにより、IPアドレスに依存した設定やアプリケーションで問題が発生することがある。
今回は、Docker Compose
で特定のコンテナに固定IPアドレスを設定する方法を記載する。
環境
Windows 11 Professional
WSL2 Ubuntu 24.04 LTS
Docker Desktop 4.41.2 (191736)
Docker version 27.4.1-1
Docker Compose version v2.32.1
設定方法
カスタムネットワークの作成
コンテナに固定IPを設定するには、まずカスタムネットワークを定義する必要がある。デフォルトネットワークでは静的IPの設定ができないためである。
services:
web:
image: nginx:latest
container_name: web_server
networks:
static_network:
ipv4_address: 172.20.0.10
networks:
static_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
設定の詳細について
ネットワーク設定
networks:
static_network:
driver: bridge # ネットワークドライバー
ipam: # IP Address Management
config:
- subnet: 172.20.0.0/16 # サブネット範囲
gateway: 172.20.0.1 # ゲートウェイアドレス
サービス設定
services:
web:
# ...existing code...
networks:
static_network:
ipv4_address: 172.20.0.10 # 固定IPアドレス
設定例
Webアプリケーション + データベース構成
services:
nginx:
image: nginx:latest
container_name: nginx_proxy
ports:
- "80:80"
networks:
app_network:
ipv4_address: 172.25.0.10
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
web_app:
image: node:18-alpine
container_name: web_application
working_dir: /app
command: npm start
networks:
app_network:
ipv4_address: 172.25.0.20
volumes:
- ./app:/app
environment:
- DB_HOST=172.25.0.30
- DB_PORT=5432
database:
image: postgres:15
container_name: postgres_db
networks:
app_network:
ipv4_address: 172.25.0.30
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data
networks:
app_network:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
gateway: 172.25.0.1
volumes:
db_data:
ロードバランサー構成
複数のWebサーバーに固定IPを設定し、ロードバランサーで分散する例
services:
load_balancer:
image: nginx:latest
container_name: lb_nginx
ports:
- "80:80"
networks:
lb_network:
ipv4_address: 172.30.0.10
volumes:
- ./lb.conf:/etc/nginx/nginx.conf
depends_on:
- web1
- web2
web1:
image: httpd:latest
container_name: web_server_1
networks:
lb_network:
ipv4_address: 172.30.0.20
volumes:
- ./web1:/usr/local/apache2/htdocs
web2:
image: httpd:latest
container_name: web_server_2
networks:
lb_network:
ipv4_address: 172.30.0.21
volumes:
- ./web2:/usr/local/apache2/htdocs
networks:
lb_network:
driver: bridge
ipam:
config:
- subnet: 172.30.0.0/24
gateway: 172.30.0.1
対応するNginxロードバランサー設定(lb.conf
)
upstream backend {
server 172.30.0.20:80;
server 172.30.0.21:80;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
複数ネットワークでの設定
一つのコンテナを複数のネットワークに参加させる場合
services:
api_gateway:
image: nginx:latest
container_name: api_gateway
ports:
- "80:80"
networks:
frontend:
ipv4_address: 192.168.1.10
backend:
ipv4_address: 192.168.2.10
web_service:
image: node:18-alpine
container_name: web_service
networks:
frontend:
ipv4_address: 192.168.1.20
database_service:
image: postgres:15
container_name: db_service
networks:
backend:
ipv4_address: 192.168.2.20
environment:
POSTGRES_DB: api_db
POSTGRES_USER: api_user
POSTGRES_PASSWORD: api_pass
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
backend:
driver: bridge
ipam:
config:
- subnet: 192.168.2.0/24
gateway: 192.168.2.1
IPv6アドレスの設定
IPv6アドレスも同様に設定できる
services:
web:
image: nginx:latest
container_name: ipv6_web
networks:
ipv6_network:
ipv4_address: 172.20.0.10
ipv6_address: 2001:db8::10
networks:
ipv6_network:
driver: bridge
enable_ipv6: true
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
- subnet: 2001:db8::/64
gateway: 2001:db8::1
動作確認とテスト
コンテナの起動
# docker-compose.ymlのあるディレクトリで実行
docker-compose up -d
IPアドレスの確認
# 特定のコンテナのIPアドレス確認
docker inspect <container_name> | grep IPAddress
# すべてのコンテナのネットワーク情報確認
docker-compose ps
# ネットワークの詳細確認
docker network ls
docker network inspect <network_name>
接続テスト
# コンテナ内からpingテスト
docker exec <container_name> ping [接続先のコンテナIP]
# コンテナ間の通信テスト
docker exec web_app curl http://[接続先のコンテナIP]:[接続先のコンテナポート]
トラブルシューティング
1. IPアドレスの競合
# エラー例
ERROR: Pool overlaps with other one on this address space
# 解決方法:異なるサブネットを使用
networks:
my_network:
ipam:
config:
- subnet: 172.21.0.0/16 # 別の範囲を指定
2. 既存ネットワークとの競合
# ネットワークの削除と再作成
docker-compose down
docker network prune
docker-compose up -d
3. IPアドレスの範囲外指定
# 正しい例:サブネット範囲内のIPを指定
networks:
my_network:
ipam:
config:
- subnet: 172.20.0.0/24 # /24なので172.20.0.1〜254が使用可能
services:
web:
networks:
my_network:
ipv4_address: 172.20.0.10 # 範囲内のIPを指定
注意事項やベストプラクティス
IPアドレスの範囲について
# プライベートIPアドレス範囲を使用
# 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
networks:
secure_network:
ipam:
config:
- subnet: 10.10.0.0/16 # 推奨
# - subnet: 8.8.8.0/24 # パブリックIPは避ける
環境変数の活用
services:
web:
image: nginx:latest
networks:
app_network:
ipv4_address: ${WEB_IP:-172.20.0.10}
networks:
app_network:
ipam:
config:
- subnet: ${SUBNET:-172.20.0.0/16}
対応する.env
ファイル
WEB_IP=172.20.0.10
DB_IP=172.20.0.20
SUBNET=172.20.0.0/16
参考
Docker Compose Networking
https://docs.docker.com/compose/networking/Docker Network Configuration
https://docs.docker.com/network/IPAM Configuration
https://docs.docker.com/reference/compose-file/networks/#ipam
おわりに
Docker Compose
でコンテナに固定IPアドレスを設定する方法を記載した。
固定IPにすることでIPアドレスを利用したアプリケーションも安定して動作させられるようになる。
このあたりは押さえておきたいなと思って備忘録としてメモした。