Docker Network Isolation & Segmentation: Multi-Tier Architectures and PCI DSS Compliance

Why the default Docker bridge network is insecure, how network segmentation prevents lateral movement, and the production incidents that happen when containers share flat networks.


Most Docker deployments use the default bridge network. Every container can talk to every other container. A compromised web server can access databases directly. A frontend container can connect to internal APIs meant only for backend services. This is functionally similar to putting all servers on the same VLAN with no firewall rules—it works, but it violates every network security principle.

In pharmaceutical production environments managing AKS clusters under HIPAA and PCI DSS compliance, network segmentation isn’t optional. Payment processing must be isolated from application tier. PHI-containing databases must not be accessible from DMZ containers. Compliance auditors specifically check for network-level isolation between security zones.

This guide covers Docker network security from basics (custom bridge networks) through multi-tier architectures (PCI DSS data isolation), encrypted overlay networks, and the production incidents that happen when containers lack proper network segmentation.


The Problem with Default Bridge Network

When Docker is installed, it creates a default bridge network (bridge). All containers without explicit network configuration attach to this network.

Security Issues with Default Bridge

  • Flat network topology: Every container can reach every other container by IP
  • No automatic DNS: Must use container IPs (harder to firewall consistently)
  • Shared broadcast domain: ARP poisoning affects all containers
  • No network policies: Cannot restrict which containers communicate
  • Difficult auditing: No visibility into inter-container traffic patterns

Real Impact: Lateral Movement

Attacker compromises a web container. Without network segmentation:

# Inside compromised web container
nmap 172.17.0.0/16  # Scan entire default bridge network
# Finds database at 172.17.0.5:5432
psql -h 172.17.0.5 -U postgres  # Direct access - no firewall

With network segmentation, database is on separate network unreachable from web tier.

[IMAGE: Network diagram comparing flat default bridge (all containers connected) vs. segmented custom networks (web/app/data tiers isolated)]


Custom Bridge Networks: The Foundation

Custom bridge networks provide container-level DNS and network isolation.

Creating Custom Networks

# Create custom bridge network
docker network create --driver bridge frontend

# Run container on custom network
docker run -d --name web --network frontend nginx

# Containers can reference each other by name
docker run -d --name app --network frontend myapp
# Inside app container: curl http://web  (DNS works automatically)

Network Isolation

Containers on different networks cannot communicate unless explicitly connected:

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - frontend  # Web only on frontend network

  app:
    image: myapp
    networks:
      - frontend  # App on both networks (acts as gateway)
      - backend

  db:
    image: postgres
    networks:
      - backend   # DB only on backend network

networks:
  frontend:
  backend:

Result: Web cannot directly access DB. App acts as controlled gateway.

[IMAGE: Diagram showing three-tier architecture with frontend/backend networks and app container as the only cross-network bridge]


Internal Networks: Air-Gapped Containers

Internal networks have no gateway to the host or internet. Containers can only communicate with each other.

Use Case: Sensitive Data Processing

# Create internal network (no external access)
docker network create --driver bridge --internal data-processing

# Run ETL pipeline on internal network
docker run -d --name etl --network data-processing my-etl-job
# This container cannot reach internet, cannot be reached from outside

PCI DSS Cardholder Data Environment (CDE)

PCI DSS Requirement 1.2.1: “Restrict inbound and outbound traffic to that which is necessary for the cardholder data environment.”

services:
  # CDE - Payment processing (internal network)
  payment-processor:
    image: payment-gateway
    networks:
      - cde-internal
    environment:
      - NO_INTERNET=true

  # CDE - Cardholder database (internal network)
  card-vault:
    image: postgres
    networks:
      - cde-internal
    volumes:
      - card-data:/var/lib/postgresql/data

  # Gateway (connects CDE to application tier)
  payment-api:
    image: payment-api-gateway
    networks:
      - frontend      # Accepts requests from application
      - cde-internal  # Proxies to payment processor
    # This is the ONLY container bridging CDE and application tier

networks:
  frontend:
    # Application tier - has internet access
  cde-internal:
    internal: true  # PCI CDE - no internet access

Compliance benefit: Auditors can verify network-level isolation by inspecting network configuration, not just application firewalls.


Encrypted Overlay Networks (Swarm Mode)

Overlay networks enable container communication across multiple Docker hosts with built-in encryption.

Creating Encrypted Overlay Network

# Initialize Swarm
docker swarm init

# Create encrypted overlay network
docker network create \
  --driver overlay \
  --opt encrypted \
  secure-backend

# Deploy service on overlay network
docker service create \
  --name api \
  --network secure-backend \
  myapi:latest

What Gets Encrypted

  • Data plane: All container-to-container traffic encrypted with AES-GCM
  • Control plane: Swarm management traffic encrypted with TLS 1.2+
  • Secret distribution: Secrets encrypted in transit between manager and worker nodes

Performance impact: ~10-15% throughput reduction due to encryption overhead. Negligible for most workloads, measurable for high-throughput data processing.

[IMAGE: Diagram showing multi-host overlay network with encrypted tunnel between Docker hosts]


Network Policies and Firewall Rules

Docker networks don’t provide Kubernetes-style NetworkPolicy. Implement egress control via iptables or third-party tools.

Restricting Outbound Traffic

# Allow container to only access specific external IPs
docker run -d \
  --name restricted-app \
  --cap-add=NET_ADMIN \
  --network custom-network \
  myapp

# Inside container or via host iptables:
iptables -A OUTPUT -d 10.0.1.50 -j ACCEPT   # Allow internal API
iptables -A OUTPUT -d 0.0.0.0/0 -j REJECT    # Block everything else

Third-Party Tools for Network Policy

  • Calico: Kubernetes-style NetworkPolicy for Docker
  • Weave Net: Encrypted overlay with built-in policies
  • Cilium: eBPF-based network security and observability

Production Failure Scenarios

Scenario 1: Database Compromise via Flat Network

The Setup: A SaaS platform ran all containers on the default bridge network. Web servers, application servers, caching layer, and PostgreSQL database all shared 172.17.0.0/16.

The Failure: A stored XSS vulnerability in the web application allowed attackers to execute JavaScript that exfiltrated user session tokens. Using a compromised admin session, attackers gained shell access to a web container.

From the web container, they scanned the network:

# Inside web container
nmap -p 5432 172.17.0.0/16
# Found PostgreSQL at 172.17.0.8

# Weak password allowed direct connection
psql -h 172.17.0.8 -U postgres
# Full database access - no network firewall between web and database

Attackers exfiltrated 340,000 user records including payment information.

What Should Have Been Done: Three-tier network architecture:

services:
  web:
    networks:
      - frontend  # Internet-facing tier

  app:
    networks:
      - frontend  # Accepts requests from web
      - backend   # Can access database

  db:
    networks:
      - backend   # NOT accessible from frontend

With this architecture, web container cannot reach database network. Even with shell access, attacker is trapped in frontend network.

Impact: PCI DSS violation, $2.8M settlement with payment processor, mandatory third-party security audit ($150K), customer notification costs ($85K).

Key Lesson: Network segmentation creates mandatory choke points. Even if an attacker gains shell access, they cannot laterally move across network boundaries.


Scenario 2: Internal API Exposed via Shared Network

The Setup: A fintech company ran microservices in Docker. An internal admin API was “secured” via obscurity—it listened on a non-standard port with no authentication, assuming it was unreachable from the internet.

The Failure: All services shared the default bridge network. A developer debugging a frontend container accidentally exposed port 8888:

docker run -p 8888:80 frontend-debug
# Meant to expose port 80, but port 8888 was ALREADY IN USE by admin API

Docker’s port mapping exposed the internal admin API to the internet. The API allowed unauthenticated access to:

  • User account modifications
  • Transaction overrides
  • Audit log deletion

Discovered by security researchers via Shodan scan. Public disclosure before company could patch.

What Should Have Been Done: Internal network for admin services:

services:
  admin-api:
    networks:
      - internal-only  # No port mappings, no internet access

  management-portal:
    networks:
      - internal-only  # Only accessible via VPN/bastion
      - frontend       # Can serve UI to authorized users

networks:
  internal-only:
    internal: true  # Cannot be reached from host

Impact: Emergency disclosure to FinCEN, SOC 2 Type II certification suspended, 6-month remediation plan mandated by regulators.


Scenario 3: ARP Spoofing on Shared Broadcast Domain

The Setup: A multi-tenant platform ran customer containers on shared Docker hosts using the default bridge network.

The Failure: A malicious customer deployed a container that performed ARP spoofing:

# Inside attacker's container
arpspoof -i eth0 -t 172.17.0.10 172.17.0.1
# Claims to be the gateway, intercepts traffic from victim container

Because all containers shared the same Layer 2 broadcast domain, ARP spoofing affected every container on the host. Attacker intercepted:

  • Database connection strings (captured during app startup)
  • API keys in HTTP headers (services using HTTP internally)
  • Session tokens (Redis cache connections)

What Should Have Been Done: Isolated networks per customer:

# Customer A's services
services:
  customer-a-app:
    networks:
      - customer-a-network

# Customer B's services (completely isolated)
services:
  customer-b-app:
    networks:
      - customer-b-network

networks:
  customer-a-network:
  customer-b-network:

Separate networks = separate broadcast domains. ARP spoofing cannot cross network boundaries.

Impact: 23 customer databases compromised, class-action lawsuit filed, platform shutdown for 48 hours during incident response, loss of enterprise customer base.

Key Lesson: Multi-tenancy requires network isolation. Shared Layer 2 domains enable broadcast-based attacks that affect all tenants.


Scenario 4: Unencrypted Cross-Host Communication

The Setup: A healthcare platform ran Docker Swarm with overlay networks but **without encryption** (--opt encrypted flag omitted). Containers communicated across 5 physical hosts.

The Failure: An attacker gained access to the data center network (compromised VPN credentials). They performed packet capture on the network switch:

# From compromised network position
tcpdump -i eth0 -w capture.pcap
# All container-to-container traffic captured in plaintext

Captured traffic included:

  • Patient health records in transit between services
  • Database credentials (PostgreSQL connection strings)
  • JWT tokens for authentication

What Should Have Been Done: Enable overlay network encryption:

docker network create \
  --driver overlay \
  --opt encrypted \  # <-- CRITICAL FLAG
  patient-data-network

Encrypted overlay networks use AES-GCM. Even with network access, attacker captures encrypted traffic.

Impact: HIPAA breach affecting 87,000 patients, HHS OCR investigation, $1.6M fine, mandatory encryption audit of all systems, CIO resignation.


Scenario 5: PCI DSS Audit Failure – Insufficient Network Segmentation

The Setup: An e-commerce platform processed credit cards in Docker containers. During PCI DSS audit, the QSA (Qualified Security Assessor) found that payment processing containers shared a network with general application services.

The Failure: PCI DSS Requirement 1.2.1 mandates restricting inbound and outbound traffic to the CDE. The platform’s architecture:

# FAILED PCI DSS - CDE not isolated
services:
  payment-gateway:
    networks:
      - app-network  # Shared with non-CDE services

  product-catalog:
    networks:
      - app-network  # Non-CDE service on same network as payment gateway

QSA identified that product catalog could directly connect to payment gateway. This violated network segmentation requirements.

What Should Have Been Done: Isolated CDE network:

services:
  # CDE - Payment processing
  payment-gateway:
    networks:
      - cde-internal  # Isolated CDE network

  # CDE - Card vault
  card-vault:
    networks:
      - cde-internal

  # Gateway - ONLY connection between CDE and application
  payment-api-proxy:
    networks:
      - app-network   # Application side
      - cde-internal  # CDE side
    # Proxy enforces protocol, validates requests, logs all access

  # Non-CDE - Product catalog
  product-catalog:
    networks:
      - app-network  # Cannot reach cde-internal

networks:
  app-network:
  cde-internal:
    internal: true  # No external access

Impact: Failed PCI DSS audit, payment processing suspended for 72 hours, $480K in lost revenue, emergency architecture redesign ($120K consultant fees), re-audit costs ($35K).

Key Lesson: Compliance frameworks like PCI DSS explicitly require network segmentation. “Application-level” security is not sufficient—network-level isolation is mandatory.

[IMAGE: Side-by-side comparison of failed vs. compliant PCI DSS network architecture with CDE boundaries marked]


Multi-Tier Network Architecture: Reference Implementation

Here’s a production-ready multi-tier architecture with defense in depth:

version: '3.8'

services:
  # DMZ / Frontend Tier
  nginx-proxy:
    image: nginx:1.27.2-alpine3.20
    ports:
      - "443:443"
    networks:
      - dmz
    deploy:
      replicas: 2

  # Application Tier
  api-gateway:
    image: api-gateway:latest
    networks:
      - dmz        # Receives requests from nginx
      - app-tier   # Forwards to backend services
    # NO direct database access

  user-service:
    image: user-service:latest
    networks:
      - app-tier   # Can be called by API gateway
      - data-tier  # Can access user database
    # Acts as controlled gateway to data tier

  # Data Tier
  user-db:
    image: postgres:16.4-alpine3.20
    networks:
      - data-tier  # NOT accessible from DMZ or app-tier directly
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - user-data:/var/lib/postgresql/data

  # Internal Admin (Air-gapped)
  admin-api:
    image: admin-api:latest
    networks:
      - admin-internal
    # No port mappings - only accessible via docker exec or VPN

  admin-db:
    image: postgres:16.4-alpine3.20
    networks:
      - admin-internal

networks:
  dmz:
    driver: bridge
    # Internet-facing tier

  app-tier:
    driver: bridge
    # Application logic tier

  data-tier:
    driver: bridge
    internal: true  # No internet access

  admin-internal:
    driver: bridge
    internal: true  # Completely air-gapped

secrets:
  db_password:
    file: ./secrets/db_password.txt

volumes:
  user-data:

Network Flow Control

FromToAllowed?Reason
Internetnginx-proxy✅ YesPublished port 443
nginx-proxyapi-gateway✅ YesBoth on dmz network
api-gatewayuser-service✅ YesBoth on app-tier network
user-serviceuser-db✅ YesBoth on data-tier network
nginx-proxyuser-db❌ NoDifferent networks, not connected
api-gatewayuser-db❌ Noapi-gateway not on data-tier network
Internetadmin-api❌ NoNo published ports, internal network
user-dbInternet❌ NoInternal network, no gateway

Network Security Best Practices

1. Never Use Default Bridge Network

Always create custom networks with explicit isolation boundaries:

# DON'T
docker run -d myapp

# DO
docker network create app-network
docker run -d --network app-network myapp

2. Use Internal Networks for Data Tier

Databases, caches, message queues should never have internet access:

docker network create --internal data-tier

3. Encrypt Overlay Networks in Production

Always use --opt encrypted for multi-host deployments:

docker network create --driver overlay --opt encrypted prod-backend

4. Implement Network Policies

Use Calico, Weave, or iptables to enforce egress control:

# Allow only specific external IPs
iptables -A OUTPUT -d 10.0.1.0/24 -j ACCEPT
iptables -A OUTPUT -d 0.0.0.0/0 -j REJECT

5. Audit Network Configuration

Regularly verify network isolation:

# List all networks and connected containers
docker network ls
docker network inspect <network-name>

# Verify internal networks have no gateway
docker network inspect data-tier | grep Gateway
# Should show: "Gateway": ""

6. Document Network Boundaries

For compliance audits, maintain network diagrams showing:

  • Security zones (DMZ, Application, Data, Admin)
  • Network boundaries
  • Gateway services bridging networks
  • Encryption status

Key Takeaways

  • Default bridge network is insecure—flat topology allows lateral movement
  • Custom bridge networks provide DNS and isolation—containers on different networks cannot communicate
  • Internal networks are air-gapped—no gateway to host or internet, essential for PCI DSS CDE
  • Overlay networks enable multi-host communication—always use encryption in production
  • Multi-tier architectures create mandatory choke points—attackers cannot bypass network boundaries even with shell access
  • Network segmentation is a compliance requirement—PCI DSS, HIPAA, and SOC 2 mandate network-level isolation
  • Layer 2 isolation prevents ARP poisoning—separate networks = separate broadcast domains

Network isolation is defense in depth. Application-level security (authentication, authorization) can fail. Network-level isolation ensures that even if an attacker compromises a container, they cannot laterally move to sensitive data tiers. For compliance-driven environments, network segmentation is not optional—it’s mandatory evidence for PCI DSS, HIPAA, and SOC 2 audits.


Previous: Image Supply Chain Security: Scanning, Signing, and SBOM

Next: Container Runtime Security: Escape Techniques and Detection

Hands-on lab: Lab 08: Network Isolation & Segmentation — Build multi-tier architectures, implement PCI DSS CDE isolation, and test network boundaries.


Related Docker Security Topics:

Scroll to Top