Skip to content

Docker — Networking & Volumes

Network Drivers

Driver Scope Use Case
bridge Single host Default; container-to-container on same host
host Single host Container shares host network stack (no isolation)
none Single host No networking (fully isolated)
overlay Multi-host Swarm / multi-node container communication
macvlan Single host Container appears as physical device on LAN

Bridge Networks

docker network create mynet                          # Create custom bridge
docker run -d --name api --network mynet myapp       # Attach on creation
docker network connect mynet existing-container      # Attach running container
docker network disconnect mynet existing-container   # Detach

Default vs Custom Bridge

Feature Default bridge Custom bridge
DNS resolution No (IP only) Yes (by container name)
Isolation All containers share it Only connected containers
Auto-attach Yes (if no --network) Explicit

Always use custom bridge networks — they provide automatic DNS and better isolation.

DNS Resolution in Compose

Compose creates a default network; services resolve each other by service name:

services:
  api:
    environment:
      DB_HOST: db           # resolves to db container IP
      REDIS_HOST: redis

  db:
    image: postgres:17-alpine

  redis:
    image: redis:7-alpine
docker compose exec api nslookup db              # Verify DNS resolution
docker compose exec api ping db                   # Test connectivity

Network Commands

docker network ls                                    # List networks
docker network inspect mynet                         # Details (connected containers, subnet)
docker network inspect mynet --format '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}'
docker network prune                                 # Remove unused networks

Exposing Ports

services:
  api:
    ports:
      - "8080:8000"          # host:container — accessible from outside
      - "127.0.0.1:8080:8000"  # bind to localhost only
    expose:
      - "8000"               # internal only (no host mapping)
Directive Host access Container-to-container Notes
ports Yes Yes Maps host port to container port
expose No Yes (same network) Documentation only in Compose — does not restrict traffic

Volumes — Types

Type Managed by Persistence Performance Use Case
Named volume Docker Survives rm Native Database data, persistent state
Bind mount Host Host filesystem Native Dev: live code reload
tmpfs Memory Lost on stop Fastest Secrets, caches, temp files

Named Volumes

services:
  db:
    image: postgres:17-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:                    # Docker manages location
docker volume ls                                     # List volumes
docker volume inspect pgdata                         # Location, driver, labels
docker volume rm pgdata                              # Delete (data loss!)
docker volume prune                                  # Remove all unused volumes

Bind Mounts

services:
  api:
    volumes:
      - ./src:/app/src                    # Read-write
      - ./config.yaml:/app/config.yaml:ro  # Read-only

Dev vs Production rule: - Dev: Bind mounts for live reload - Production: Named volumes (or baked into image)

tmpfs Mounts

services:
  api:
    tmpfs:
      - /tmp
      - /app/cache:size=100M

Stored in RAM — fast, ephemeral, good for caches and secrets at runtime.

Volume Backup & Restore

# Backup named volume to tarball
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
  tar czf /backup/pgdata-backup.tar.gz -C /data .

# Restore from tarball
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
  sh -c "cd /data && tar xzf /backup/pgdata-backup.tar.gz"

Multi-Network Isolation

services:
  api:
    networks:
      - frontend
      - backend

  db:
    networks:
      - backend           # Not accessible from frontend

  nginx:
    networks:
      - frontend          # Cannot reach db directly

networks:
  frontend:
  backend:
nginx ──frontend──► api ──backend──► db
          ✗ nginx cannot reach db directly

Volume Permissions

Common issue: container user cannot write to mounted volume.

# In Dockerfile
RUN groupadd -r appgrp && useradd -r -g appgrp -u 1000 appusr
RUN mkdir -p /app/data && chown appusr:appgrp /app/data
USER appusr
# Or fix on host
sudo chown -R 1000:1000 ./data