Skip to main content

docker-compose-networking

Use when configuring networks and service communication in Docker Compose including bridge networks, overlay networks, service discovery, and inter-service communication.

Source facts

Repository
TheBushidoCollective/han
Last source activity
February 11, 2026 at 17:47
Detected SKILL.md language
English
Stars
198
Forks
24

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
docker-compose-networking
user-invocable
false
description
Use when configuring networks and service communication in Docker Compose including bridge networks, overlay networks, service discovery, and inter-service communication.
allowed-tools
["Bash","Read"]
# Docker Compose Networking Master network configuration and service communication patterns in Docker Compose for building secure, scalable multi-container applications. ## Default Bridge Network Docker Compose automatically creates a default bridge network for all services in a compose file: ```yaml version: '3.8' services: frontend: image: nginx:alpine ports: - "80:80" # Can reach backend using service name as hostname backend: image: node:18-alpine command: node server.js # Accessible at hostname 'backend' from frontend database: image: postgres:15-alpine environment: POSTGRES_PASSWORD: secret # Accessible at hostname 'database' from backend ``` In this setup: - All services can communicate using service names as hostnames - Frontend can reach backend at `http://backend:3000` - Backend can reach database at `postgres://database:5432` - Only frontend's port 80 is exposed to host ## Custom Bridge Networks Define custom networks for service isolation and segmentation: ```yaml version: '3.8' services: frontend: image: nginx:alpine networks: - frontend-network ports: - "80:80" api: image: node:18-alpine networks: - frontend-network - backend-network environment: DATABASE_URL: postgresql://db:5432/app database: image: postgres:15-alpine networks: - backend-network environment: POSTGRES_PASSWORD: secret POSTGRES_DB: app volumes: - db-data:/var/lib/postgresql/data cache: image: redis:7-alpine networks: - backend-network command: redis-server --appendonly yes volumes: - redis-data:/data networks: frontend-network: driver: bridge backend-network: driver: bridge internal: true volumes: db-data: redis-data: ``` Network isolation: - Frontend can only reach API - Frontend cannot reach database or cache directly - API can reach all services - Backend network is internal (no external access) ## Network Aliases Configure multiple hostnames for service discovery: ```yaml version: '3.8' services: web: image: nginx:alpine networks: public: aliases: - website - www - web-server internal: aliases: - web-internal api: image: node:18-alpine networks: public: aliases: - api-server - backend internal: aliases: - api-internal depends_on: - database database: image: postgres:15-alpine networks: internal: aliases: - db - postgres - primary-db environment: POSTGRES_PASSWORD: secret networks: public: driver: bridge internal: driver: bridge internal: true ``` Services can be reached by any of their aliases: - `http://website`, `http://www`, `http://web-server` all reach web service - `postgresql://db:5432`, `postgresql://postgres:5432` both reach database ## Static IP Addresses Assign fixed IP addresses for services requiring stable networking: ```yaml version: '3.8' services: loadbalancer: image: nginx:alpine networks: app-network: ipv4_address: 172.28.1.10 ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro app-1: image: myapp:latest networks: app-network: ipv4_address: 172.28.1.11 environment: APP_ID: "1" app-2: image: myapp:latest networks: app-network: ipv4_address: 172.28.1.12 environment: APP_ID: "2" app-3: image: myapp:latest networks: app-network: ipv4_address: 172.28.1.13 environment: APP_ID: "3" database: image: postgres:15-alpine networks: app-network: ipv4_address: 172.28.1.20 environment: POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data networks: app-network: driver: bridge ipam: driver: default config: - subnet: 172.28.0.0/16 gateway: 172.28.1.1 volumes: pgdata: ``` ## External Networks Connect to existing Docker networks created outside Compose: ```yaml version: '3.8' services: api: image: node:18-alpine networks: - app-network - shared-network environment: DATABASE_URL: postgresql://db:5432/app database: image: postgres:15-alpine networks: - app-network environment: POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data networks: app-network: driver: bridge shared-network: external: true name: company-shared-network volumes: pgdata: ``` Create external network first: ```bash docker network create company-shared-network docker compose up -d ``` ## Host Network Mode Use host networking for maximum performance (Linux only): ```yaml version: '3.8' services: high-performance-app: image: myapp:latest network_mode: "host" environment: BIND_ADDRESS: "0.0.0.0" PORT: "8080" # No port mapping needed - directly uses host's network stack monitoring: image: prometheus:latest network_mode: "host" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.listen-address=0.0.0.0:9090' volumes: prometheus-data: ``` Note: Host networking bypasses Docker network isolation and is typically used for monitoring tools or high-throughput applications. ## Service Discovery and DNS Configure DNS resolution and service discovery: ```yaml version: '3.8' services: api: image: node:18-alpine networks: - app-network dns: - 8.8.8.8 - 8.8.4.4 dns_search: - company.local extra_hosts: - "legacy-api.company.local:192.168.1.100" - "auth-service.company.local:192.168.1.101" environment: DATABASE_HOST: database.company.local database: image: postgres:15-alpine networks: app-network: aliases: - database.company.local - db.company.local hostname: primary-database domainname: company.local environment: POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data networks: app-network: driver: bridge driver_opts: com.docker.network.bridge.name: br-company-app volumes: pgdata: ``` ## Link Containers (Legacy) While `links` is deprecated, understanding it helps migrate legacy configurations: ```yaml version: '3.8' services: # Modern approach - use networks instead web: image: nginx:alpine networks: - app-network depends_on: - api api: image: node:18-alpine networks: - app-network depends_on: - database environment: # Use service name as hostname DATABASE_URL: postgresql://database:5432/app database: image: postgres:15-alpine networks: - app-network environment: POSTGRES_PASSWORD: secret networks: app-network: driver: bridge ``` ## Multi-Network Architecture Complex applications with multiple isolated networks: ```yaml version: '3.8' services: nginx: image: nginx:alpine networks: - public ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - frontend - api frontend: image: react-app:latest networks: - public - frontend-tier environment: API_URL: http://api:3000 api: image: node-api:latest networks: - frontend-tier - backend-tier environment: DATABASE_URL: postgresql://postgres:5432/app REDIS_URL: redis://cache:6379 QUEUE_URL: amqp://rabbitmq:5672 depends_on: - database - cache - queue worker: image: node-worker:latest networks: - backend-tier environment: DATABASE_URL: postgresql://postgres:5432/app QUEUE_URL: amqp://rabbitmq:5672 depends_on: - database - queue deploy: replicas: 3 database: image: postgres:15-alpine networks: - backend-tier environment: POSTGRES_PASSWORD: secret POSTGRES_DB: app volumes: - pgdata:/var/lib/postgresql/data cache: image: redis:7-alpine networks: - backend-tier command: redis-server --appendonly yes volumes: - redis-data:/data queue: image: rabbitmq:3-management-alpine networks: - backend-tier - management ports: - "15672:15672" # Management UI environment: RABBITMQ_DEFAULT_USER: admin RABBITMQ_DEFAULT_PASS: secret volumes: - rabbitmq-data:/var/lib/rabbitmq monitoring: image: prometheus:latest networks: - management ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus networks: public: driver: bridge frontend-tier: driver: bridge internal: true backend-tier: driver: bridge internal: true management: driver: bridge volumes: pgdata: redis-data: rabbitmq-data: prometheus-data: ``` Network segmentation: - Public: Internet-facing services (nginx, frontend) - Frontend-tier: Frontend and API communication - Backend-tier: API, workers, databases, cache, queue - Management: Monitoring and administration tools ## Port Publishing Strategies Control how services expose ports: ```yaml version: '3.8' services: # Short syntax - host:container web: image: nginx:alpine ports: - "80:80" - "443:443" networks: - public # Long syntax with protocol specification api: image: node:18-alpine ports: - target: 3000 published: 3000 protocol: tcp mode: host networks: - app-network # Random host port app: image: myapp:latest ports: - "3000" # Docker assigns random host port networks: - app-network # Bind to specific host interface admin: image: admin-panel:latest ports: - "127.0.0.1:8080:80" # Only accessible from localhost networks: - admin-network # UDP protocol dns: image: bind9:latest ports: - "53:53/udp" - "53:53/tcp" networks: - dns-network # Range of ports streaming: image: rtmp-server:latest ports: - "1935:1935" - "8080-8089:8080-8089" networks: - streaming-network networks: public: app-network: admin-network: internal: true dns-network: streaming-network: ``` ## Container Communication Patterns ### Request-Response Pattern ```yaml version: '3.8' services: gateway: image: nginx:alpine networks: - frontend ports: - "80:80" volumes: - ./nginx-gateway.conf:/etc/nginx/nginx.conf:ro service-a: image: service-a:latest networks: - frontend - backend environment: SERVICE_B_URL: http://service-b:8080 DATABASE_URL: postgresql://db:5432/service_a service-b: image: service-b:latest networks: - frontend - backend environment: DATABASE_URL: postgresql://db:5432/service_b database: image: postgres:15-alpine networks: - backend environment: POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data networks: frontend: driver: bridge backend: driver: bridge internal: true volumes: pgdata: ``` ### Pub-Sub Pattern ```yaml version: '3.8' services: publisher: image: publisher:latest networks: - messaging environment: REDIS_URL: redis://redis:6379 depends_on: - redis subscriber-1: image: subscriber:latest networks: - messaging environment: REDIS_URL: redis://redis:6379 SUBSCRIBER_ID: "1" depends_on: - redis subscriber-2: image: subscriber:latest networks: - messaging environment: REDIS_URL: redis://redis:6379 SUBSCRIBER_ID: "2" depends_on: - redis redis: image: redis:7-alpine networks: - messaging command: redis-server --appendonly yes volumes: - redis-data:/data networks: messaging: driver: bridge driver_opts: com.docker.network.bridge.enable_icc: "true" volumes: redis-data: ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub