Container linking (legacy) vs networks

Why --link gave way to user-defined networks.

Intermediate10 min · lesson 14 of 30

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.

terminal
# 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.

Legacy links vs user-defined networks
legacy --link (deprecated)
point-to-point
wire each pair by name
injects env vars
leaks the target’s config
breaks on recreate
brittle, one-directional
user-defined network (use this)
automatic DNS
reach any peer by name
follows recreation
name -> current IP
isolation + aliases
no env leakage
Anything --link did, a user-defined network does better. Compose creates one for you automatically.

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.”

terminal
$ 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 db
172.19.0.2 db
Treat --link as read-only history
You will see --link in older docs and Stack Overflow answers — recognize it, but do not build with it. It is deprecated, leaks the linked container’s environment, and only works on the default bridge. Every current design uses user-defined networks (or Compose, which makes one for you).