Container linking (legacy) vs networks
Why --link gave way to user-defined networks.
Older Docker tutorials lean on --link, the legacy way to connect containers: docker run --link db:database let a container reach another by an alias and injected connection details. It still parses, but it is deprecated, and understanding why explains the whole modern networking model. --link was point-to-point, brittle, and one-directional — it wired specific containers together by name at run time.
# LEGACY --link (avoid): wires web -> db, injects DB_* env vars and a hosts entry$ docker run -d --name db postgres:16$ docker run -d --name web --link db:database myapp:1.0# web can now reach "database", but the link is fragile and one-way
Why links gave way to networks
Legacy links had real problems: they broke when the target container was recreated, they injected environment variables that leaked the linked container’s config (including secrets), they only worked on the default bridge, and they described a rigid graph of individual containers. User-defined networks fixed all of it at once — automatic DNS by container name, resolution that follows a recreated container, isolation between networks, and no config-leaking env injection.
The modern equivalent
The replacement is simply to put both containers on the same user-defined network and reach the peer by name. In Compose this is automatic — every stack gets its own network and services resolve each other by service name — which is why you almost never see --link in current Compose files. If you meet --link in an old tutorial, mentally translate it to “put them on a network together.”
$ docker network create appnet$ docker run -d --name db --network appnet postgres:16$ docker run -d --name web --network appnet myapp:1.0 # reaches db by name, no --link$ docker exec web getent hosts db172.19.0.2 db