Docker Network Lifecycle Management
We’ve now used Docker networks enough to stop treating them as something that just appears when a container starts.
A network is a Docker resource with its own lifecycle.
You can create one, inspect it, attach containers to it, detach containers from it, and eventually remove it.
The useful mental model is:
Network
|
+── exists
|
+── containers connected
|
+── no containers connected
|
└── removedLet’s walk through that lifecycle.
List Existing Networks
Start by seeing what networks Docker already knows about:
docker network lsOn a typical Docker installation you’ll see built-in networks such as:
NETWORK ID NAME DRIVER SCOPE
... bridge bridge local
... host host local
... none null localThese are Docker’s built-in networks.
You normally don’t remove these as part of ordinary cleanup.
The networks we create ourselves have their own lifecycle.
Create a Network
Create a user-defined bridge network:
docker network create app-netDocker returns the network ID.
Now list the networks again:
docker network lsYou should see:
app-netThe network now exists independently of any container.
That’s important:
docker network create app-net
|
v
app-net
|
+── no containers yetA network doesn’t need a container to exist.
Inspect the Network
To see what Docker knows about the network:
docker network inspect app-netYou’ll find information such as:
- network name
- driver
- subnet
- gateway
- connected containers
When the network is newly created, the container list will be empty.
Conceptually:
app-net
|
+── Driver: bridge
|
+── Subnet: ...
|
+── Gateway: ...
|
└── Containers: noneThis is one of the most useful commands when something about Docker networking isn’t behaving as expected.
Connect a Container
Now create a container and connect it to the network:
docker container run -d \
--name app \
--network app-net \
alpine:latest \
sleep 300The network now has a container attached to it:
app-net
|
└── appInspect it again:
docker network inspect app-netYou should now see app under the connected containers.
The lifecycle has moved from:
Network exists
↓
No containersto:
Network exists
↓
Container connectedA Network Can Have Multiple Containers
Create another container:
docker container run -d \
--name database \
--network app-net \
alpine:latest \
sleep 300Now:
app-net
/ \
/ \
app databaseBoth containers are members of the same user-defined bridge network.
They can use the network features you’ve already learned, including Docker’s built-in name resolution.
For example, from app:
docker container exec app ping -c 1 databaseThe exact output isn’t important here.
The important point is that database is now a container connected to the same user-defined network.
Disconnect a Container
A network doesn’t permanently belong to a container.
You can explicitly disconnect a container:
docker network disconnect app-net databaseNow:
app-net
|
└── appdatabase is no longer connected.
You can confirm this with:
docker network inspect app-netThe container should no longer appear in the network’s connected-container list.
The lifecycle now looks like:
app-net
|
+── app
|
└── database disconnectedConnect It Again
If you change your mind:
docker network connect app-net databaseNow database is back:
app-net
/ \
/ \
app databaseThis is useful when a container already exists and you want to change which networks it belongs to.
Notice the difference between:
docker container run --network app-net ...and:
docker network connect app-net <container>The first connects the container to the network as part of container creation.
The second connects an existing container to the network.
A Container Can Be on Multiple Networks
This is an important property of Docker networking.
A container isn’t necessarily limited to one network.
For example:
docker network create frontend
docker network create backendThen create a container on frontend:
docker container run -d \
--name app \
--network frontend \
alpine:latest \
sleep 300Connect the same container to backend:
docker network connect backend appNow:
flowchart LR
A["app"]
B["backend"]
F["frontend"]
A --> B
A --> F
The same container belongs to both networks.
This can be useful when a container needs to communicate with different groups of containers.
You don’t need to memorize complex architecture here. Just remember:
A container can be connected to more than one Docker network.
What Happens When a Container Is Removed?
This is where the network lifecycle differs from the container lifecycle.
Remove a container:
docker container rm -f databaseThe container disappears.
The network remains:
app-net
|
└── appIf database was the only container, the network would simply become empty:
app-net
|
└── no containersDocker does not automatically remove the user-defined network just because its containers disappeared.
That’s important because you may want to reuse the same network later.
An Empty Network Is Still a Network
Suppose you remove every container from app-net.
You can still run:
docker network inspect app-netThe network exists.
You can then create a completely new container and attach it to the same network:
docker container run -d \
--name new-app \
--network app-net \
alpine:latest \
sleep 300So:
Network
|
+── empty
|
└── reusableThis is another example of Docker resources having independent lifecycles.
Remove a Network
When you no longer need the network:
docker network rm app-netDocker removes the network.
But there is an important restriction.
A network that still has containers connected to it cannot simply be removed.
For example:
app-net
|
+── app
+── databaseTrying:
docker network rm app-netwill fail because the network is still in use.
Docker makes you deal with the connected containers first.
You can either:
docker network disconnect app-net app
docker network disconnect app-net databaseand then remove the network:
docker network rm app-netor remove the containers that are using the network.
The exact cleanup depends on whether those containers are still needed.
Network Pruning
Over time, you might create networks for experiments and forget about them.
Docker provides:
docker network pruneThis removes unused user-defined networks.
Docker asks for confirmation first.
You can skip the confirmation with:
docker network prune --forceThe important word is:
unused
A network with containers still connected to it is not considered unused in the normal sense relevant to pruning.
Built-in networks such as bridge, host, and none are not simply wiped out by this cleanup.
Warning
docker network prune is a cleanup command. Before using it on a real Docker host, make sure unused networks are genuinely disposable.
Useful Filters
You can filter network listings:
docker network ls --filter name=appThis is handy when the host has many networks.
You can also filter by driver:
docker network ls --filter driver=bridgeThe exact filters you use will depend on what you’re trying to find, but the important pattern is:
docker network ls --filter ...Useful Network Commands
The core commands are small enough to remember:
| Command | Purpose |
|---|---|
docker network ls | List networks |
docker network create NAME | Create a network |
docker network inspect NAME | Inspect a network |
docker network connect NETWORK CONTAINER | Connect an existing container |
docker network disconnect NETWORK CONTAINER | Disconnect a container |
docker network rm NAME | Remove a network |
docker network prune | Remove unused networks |
And when creating a container:
docker container run \
--network NETWORK \
IMAGEconnects it to the specified network at creation time.
The Network Lifecycle
Now put the whole lifecycle together:
stateDiagram-v2
[*] --> Created: docker network create
Created --> Connected: container joins
Connected --> Connected: another container joins
Connected --> Empty: last container disconnects
Connected --> Empty: last container removed
Empty --> Connected: container joins again
Empty --> Removed: docker network rm
Empty --> Removed: docker network prune
Removed --> [*]
The important states are:
Created
↓
Connected
↓
Empty
↓
RemovedAnd the lifecycle is independent from any one container.
A container can come and go while the network survives.
Network vs Container Lifecycle
This distinction is worth seeing side by side.
Container
create
↓
running
↓
stopped
↓
removedNetwork
create
↓
containers connected
↓
empty
↓
removedRemoving the container doesn’t automatically destroy the network.
Removing the network doesn’t mean “remove all containers” either — Docker will normally refuse to remove a network while containers are still connected.
They are separate resources.
A Practical Cleanup Sequence
Suppose you created:
app-net
|
+── app
+── databaseand the experiment is finished.
One clean approach is:
docker container rm -f app database
docker network rm app-netAfter that:
docker network lsshould no longer show app-net.
For a forgotten collection of unused networks, you can instead use:
docker network pruneThe difference is:
network rm
↓
"I know exactly which network I want to delete."
network prune
↓
"Clean up unused networks."What You Should Remember
You don’t need to memorize every flag.
Remember the lifecycle:
CREATE
↓
CONNECT
↓
USE
↓
DISCONNECT
↓
REMOVEAnd the core commands:
docker network create
docker network ls
docker network inspect
docker network connect
docker network disconnect
docker network rm
docker network pruneThe most important conceptual point is:
A Docker network is an independent resource. Containers can join and leave it without determining whether the network itself exists.
That same lifecycle thinking will make Docker volumes much easier to understand.