Compose, Networking & Volumes
.mdVerified against Docker 29.1.5 (Compose v2, built in), flags verified via `docker <cmd> --help`, 2026-08-21 · official docs
Running multi-container stacks with Compose, and the networking/volume primitives underneath them.
Compose — starting and stopping a stack#
docker compose up -d # start everything defined in compose.yaml, detached
docker compose up -d --build # rebuild images first
docker compose down # stop and remove containers + default network
docker compose down -v # also remove named volumes (destroys persisted data)
docker compose stop # stop without removing containersdocker compose (space, no hyphen) is the current, built-in form — the old standalone docker-compose binary is deprecated. down -v is destructive: it deletes any named volumes the stack owns, including database data, so it's not the default even though it's tempting to reach for when "cleaning up."
Compose — inspecting a running stack#
docker compose ps
docker compose logs -f
docker compose logs -f my-service # logs for one service only
docker compose exec my-service /bin/bash
docker compose topCompose — rebuilding and scaling#
docker compose build my-service
docker compose up -d --force-recreate my-service # recreate even if config hasn't changed
docker compose up -d --scale worker=3 # run 3 replicas of the worker serviceNetworks#
docker network ls
docker network create my-network --driver bridge --subnet 172.20.0.0/16
docker network connect my-network my-container
docker network inspect my-network # see connected containers + IPs
docker network rm my-networkCompose creates its own bridge network per project automatically, and every service in that compose file can reach every other one by service name (DNS resolution built in) — you rarely need docker network create by hand unless you're connecting containers started outside Compose.
Network drivers and static IP assignment#
docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my-network
docker network create --driver bridge --internal my-network # no external/outbound connectivity at all
docker network create --driver bridge --attachable my-swarm-net # let standalone `docker run` containers join a swarm-scope network
docker network connect --ip 172.20.0.10 my-network my-container # attach with a fixed IP instead of DHCP-assigned
docker network connect --alias db my-network my-container # give the container an extra DNS alias on that networkThe default driver is bridge — an isolated, host-private virtual network with NAT out to the host. host (--network host on docker run) removes network isolation entirely and shares the host's network namespace directly, trading isolation for eliminating NAT overhead; --internal builds a bridge network with no route out, useful for a database tier that should never reach the internet even if a container on it is compromised. overlay and macvlan drivers exist for multi-host/swarm and "container gets its own MAC on the physical LAN" use cases respectively, but aren't relevant to single-host Compose development.
Volumes#
docker volume ls
docker volume create my-data
docker volume inspect my-data
docker run -v my-data:/var/lib/postgresql/data postgres:16 # named volume — Docker-managed storage
docker run -v ./local-dir:/app/data myapp:latest # bind mount — a real host path
docker volume rm my-data
docker volume prune # remove all volumes not used by any containerA named volume (my-data:/path) is managed by Docker and portable across containers; a bind mount (./local-dir:/path) ties a container directly to a specific path on the host filesystem — reach for a named volume for anything that needs to survive a container being recreated but doesn't need to be human-editable from the host.