Docker Compose Configuration
Set Static IP Addresses for Services using IPAM
In Docker Compose, you can assign static IP addresses to your containers within a custom network. This ensures consistent communication between services, especially when specific IP addresses are required. Docker Compose Network
Example with Static IPs
version: '3.9'
services: app: image: your-app-image container_name: app_service ... networks: example_network: ipv4_address: 172.99.0.10
db: image: your-db-image container_name: db_service ... networks: example_network: ipv4_address: 172.99.0.2
nginx: image: nginx:latest container_name: nginx_service ... networks: example_network: ipv4_address: 172.99.0.3
networks: example_network: driver: bridge ipam: config: - subnet: 172.99.0.0/24 external: falseInspect the created network to verify assignments:
docker network inspect example_networkSet Multiple Subnets
Defining multiple subnets in a single Docker network allows you to:
1. Separate groups of services (e.g., databases in one subnet, caches in another).
2. Use different routing or gateways for different traffic flows.
3. Allocate different IP address spaces for legacy services vs dynamic ones.
version: '3.9'
services: app: image: your-app networks: example_network: ipv4_address: 172.99.0.10
cache: image: redis:7 networks: example_network: ipv4_address: 172.99.1.5
networks: example_network: driver: bridge ipam: config: - subnet: 172.99.0.0/24 - subnet: 172.99.1.0/24Set IP Range
What it is / When to use?
The
ip_rangeoption restricts the pool of IP addresses Docker can dynamically assign within a subnet. This is useful when:
1. You want to reserve a portion of the subnet for static IP assignments.
2. You need stricter control over which addresses Docker is allowed to allocate.
3. You’re mixing static and dynamic IPs in the same subnet.
version: '3.9'
services: app1: image: your-app networks: example_network: {}
app2: image: your-app networks: example_network: {}
db: image: postgres:16 networks: example_network: ipv4_address: 172.99.0.5 # static, outside the dynamic range
networks: example_network: driver: bridge ipam: config: - subnet: 172.99.0.0/24 ip_range: 172.99.0.128/25Add Healthcheck to Service
Ensure containers are only marked as healthy when their core functionality is available and responsive.
APP/Web Server
services:... api: container_name: api restart: unless-stopped ports: - "8000:8000" healthcheck: test: ["CMD", "curl", "--fail", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 start_period: 5s...MySQL
services:... mysql: image: mysql:8.0 container_name: mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: db MYSQL_USER: user MYSQL_PASSWORD: pass ports: - "3306:3306" healthcheck: # not best practices test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-prootpass"] interval: 30s timeout: 10s retries: 5 start_period: 20s...MariaDB
services:... mysql: image: mysql:8.0 container_name: mysql restart: unless-stopped ports: - "3306:3306" healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s timeout: 5s retries: 3 start_period: 1m...PostgreSQL
services:... postgres: image: postgres:16 container_name: postgres restart: unless-stopped environment: POSTGRES_USER: user POSTGRES_PASSWORD: pass POSTGRES_DB: db ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d db -h localhost"] interval: 30s timeout: 10s retries: 5 start_period: 20s...Redis
services:... redis: image: redis:7 container_name: redis restart: unless-stopped ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 5 start_period: 10s...