docker-compose-networking

Docker Compose Networking

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "docker-compose-networking" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-docker-compose-networking

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:

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:

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:

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:

Static IP Addresses

Assign fixed IP addresses for services requiring stable networking:

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:

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:

docker network create company-shared-network docker compose up -d

Host Network Mode

Use host networking for maximum performance (Linux only):

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:

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:

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:

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:

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

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

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:

Network Troubleshooting Configuration

Enable debugging and monitoring:

version: '3.8'

services: app: image: myapp:latest networks: app-network: aliases: - primary-app cap_add: - NET_ADMIN - NET_RAW

debug: image: nicolaka/netshoot:latest networks: - app-network command: sleep infinity cap_add: - NET_ADMIN - NET_RAW stdin_open: true tty: true

database: image: postgres:15-alpine networks: app-network: aliases: - db environment: POSTGRES_PASSWORD: secret

networks: app-network: driver: bridge driver_opts: com.docker.network.bridge.enable_ip_masquerade: "true" com.docker.network.driver.mtu: "1500" ipam: driver: default config: - subnet: 172.28.0.0/16

Debug commands:

Enter debug container

docker compose exec debug bash

Test connectivity

ping app curl http://app:8080/health

Check DNS resolution

nslookup app dig app

Network scanning

nmap -p- app

Trace route

traceroute app

Monitor traffic

tcpdump -i eth0 -n

IPv6 Networking

Enable IPv6 support:

version: '3.8'

services: web: image: nginx:alpine networks: - ipv6-network ports: - "80:80"

api: image: node:18-alpine networks: ipv6-network: ipv6_address: 2001:db8:1::10

database: image: postgres:15-alpine networks: ipv6-network: ipv6_address: 2001:db8:1::20 environment: POSTGRES_PASSWORD: secret

networks: ipv6-network: driver: bridge enable_ipv6: true ipam: driver: default config: - subnet: 172.28.0.0/16 - subnet: 2001:db8:1::/64

When to Use This Skill

Use docker-compose-networking when you need to:

  • Configure custom network topologies for multi-container applications

  • Implement network segmentation and service isolation

  • Set up service discovery and inter-service communication

  • Design secure network architectures with frontend/backend separation

  • Configure static IP addresses for services

  • Connect to external Docker networks

  • Implement complex microservices communication patterns

  • Troubleshoot network connectivity issues

  • Configure DNS resolution and hostname aliases

  • Set up pub-sub or message queue architectures

  • Enable IPv6 networking

  • Optimize network performance with host networking

  • Configure port publishing and exposure strategies

Best Practices

Use Custom Networks for Isolation: Always create custom networks instead of relying solely on the default network for better security and organization.

Implement Network Segmentation: Separate frontend, backend, and data tiers into different networks to limit attack surface.

Use Internal Networks: Mark backend networks as internal: true to prevent external access to sensitive services like databases.

Prefer Service Names Over IPs: Use Docker's built-in DNS and service names instead of hardcoding IP addresses for maintainability.

Configure Health Checks: Implement health checks to ensure services are ready before routing traffic to them.

Use Network Aliases: Define meaningful aliases for services to support multiple naming conventions and easier migration.

Avoid Host Networking Unless Necessary: Use bridge networks by default; host networking should only be used for specific performance requirements.

Document Network Architecture: Clearly comment your network design and document which services can communicate with each other.

Use Depends_on Wisely: Combine depends_on with health checks to ensure services start in the correct order.

Implement Least Privilege: Only expose ports that absolutely need to be accessible from outside the Docker network.

Use Environment Variables for URLs: Configure service endpoints through environment variables for flexibility across environments.

Test Network Isolation: Regularly verify that services can only communicate through intended network paths.

Configure Appropriate MTU: Set MTU values based on your network infrastructure to avoid fragmentation issues.

Use External Networks for Shared Resources: When multiple Compose projects need to communicate, use external networks rather than duplicating services.

Monitor Network Performance: Use tools like docker stats and dedicated monitoring containers to track network usage and identify bottlenecks.

Common Pitfalls

Exposing All Services Publicly: Don't publish ports for services that should only be accessed internally; use networks instead of port publishing.

Hardcoding IP Addresses: Avoid static IP addresses unless absolutely necessary; rely on service discovery instead.

Using Default Network Only: Not creating custom networks misses opportunities for proper segmentation and isolation.

Ignoring Network Modes: Using the wrong network mode (bridge vs host vs overlay) for your use case can cause connectivity or performance issues.

Missing Network Dependencies: Not properly configuring depends_on can cause services to fail when trying to connect to unavailable services.

Overusing Host Networking: Using network_mode: host unnecessarily breaks container isolation and portability.

Not Using Internal Networks: Failing to mark backend networks as internal leaves databases and sensitive services exposed.

Mixing Network Modes: Trying to publish ports or connect to networks when using network_mode: host causes configuration errors.

Circular Network Dependencies: Creating network dependencies that form a circle prevents containers from starting properly.

Ignoring DNS Configuration: Not configuring DNS properly can cause name resolution failures in containerized applications.

Subnet Conflicts: Using IP ranges that conflict with host or other Docker networks causes routing issues.

Not Testing Network Policies: Assuming network isolation works without testing can leave security vulnerabilities.

Exposing Management Interfaces: Publishing management ports (like RabbitMQ, Redis, PostgreSQL) without authentication or IP restrictions.

Using Links Instead of Networks: The deprecated links feature should be replaced with modern network configuration.

Ignoring Network Driver Options: Not configuring driver options like MTU or IP masquerade can cause subtle connectivity problems in production.

Resources

Official Documentation

  • Docker Compose Networking

  • Docker Network Drivers

  • Docker DNS

Network Troubleshooting

  • Nicolaka Netshoot - Network troubleshooting container

  • Docker Network Inspect

Architecture Patterns

  • Microservices Network Patterns

  • Docker Security Best Practices

Tools

  • Docker Network Commands

  • Compose Network Reference

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

android-jetpack-compose

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastapi-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

storybook-story-writing

No summary provided by upstream source.

Repository SourceNeeds Review