1.4Networks: making containers talk to each other
The essentials in 30 seconds
- The default bridge isolates without naming: each container has a private IP, but names do not resolve there — you tinker with IPs that change.
- One network per application: docker network create monapp then --network monapp on each run — from the web, the database is reached by its --name (bdd:5432).
- Published frontend, internal database: publish (-p) only the web; the database stays invisible from the outside but reachable from the inside — inspect and ping prove the wiring.
Running mini-case — Idir wires web + database
Idir's demo grows: his frontend must talk to the database by name, not by an IP noted on a sticky note. He creates a monapp network, relaunches bdd on it without publishing its port, then relaunches web on it with -p 8080:80. From the web, he pings bdd: it answers by name. When a colleague suggests « publishing the database to test », Idir refuses: exposing Postgres to the whole machine for a test installs a dangerous habit.
Continuation of cases 1.1-1.3 — Idir moves from isolated containers to a wired application.
1. The default network isolates
Each container gets a private IP on the default bridge network, but names do not resolve there: you tinker with IPs that change on each relaunch. Hard-coding an IP in the config programs the next outage.
The good practice is to create a dedicated network per application: Docker enables name resolution there.
2. One network per application
docker network create monapp then --network monapp on each service run: from the web, the database is reached by its --name (bdd:5432). Publish (-p) only the frontend; the database stays invisible from the outside but reachable from the inside.
This « one network, one published frontend » pattern is exactly what Compose will automate at level 3.
3. Seeing is believing: inspect and ping
docker network ls and inspect show who is plugged where. From a container, ping bdd or a connection proves resolution. Method: create, plug, prove — in that order.
If two containers cannot see each other, first check they share the same network, then that you reach the name and not an IP.
🔎 Concrete example — 🔎 Concrete example — Web + database on a private network
Idir's wired application: one frontend, one invisible database.
docker network create monapp
docker run -d --name bdd --network monapp -e POSTGRES_PASSWORD=secret postgres:16.4
docker run -d --name web --network monapp -p 8080:80 nginx:1.27
docker exec web ping -c2 bdd
Reading: ping succeeds by name, without publishing the database.
Lesson: publishing the database would have exposed Postgres to the whole machine.
Section vocabulary
- Bridge
- Default isolated network driver between containers and host; no name resolution.
Simple example: The default network where Idir tinkered with IPs.
What it is not: an application network with DNS by name.
Reflex: default = temporary, app = dedicated network.
- Dedicated network
- Network created per application (network create), with DNS name resolution between its containers.
Simple example: monapp, where web reaches bdd:5432.
What it is not: one network per container.
Reflex: separate by app, not by service.
- Name resolution
- Reaching a container by its --name rather than its changing IP.
Simple example: ping bdd from web, valid after each relaunch.
What it is not: an IP hard-coded in the config.
Reflex: always the name, never the IP.
- Frontend
- The only service published to the outside (the web); everything else stays internal.
Simple example: web on 8080:80, bdd unpublished at Idir's.
What it is not: every service published « just in case ».
Reflex: only one published: the frontend.
In practice — In practice — Wiring a mini-app
- Create a monapp network.
- Launch the database on it, WITHOUT port publishing.
- Launch the web on it, WITH 8080:80 publishing.
- From the web (exec), ping the database by name.
Script ready to say — wiring two containers (30 s)
« I create one network per app: network create monapp. I plug the database on it without publishing its port, and the web on it with -p 8080:80. From the web, I ping the database by name: bdd. The frontend is published, the database never is. »
Say while typing create then both runs; finish with the successful ping.
Copy-paste template — two-service app
docker network create monapp
docker run -d --name bdd --network monapp -e POSTGRES_PASSWORD=secret postgres:16.4
docker run -d --name web --network monapp -p 8080:80 nginx:1.27
docker exec web ping -c2 bdd # proof by name
docker network ls # check the connections
Idir's app
As above: monapp, internal bdd, published web — the pattern Compose will automatically reuse at level 3.
Two apps coexist
monapp and compta, two separate networks: each app's bdd is reached by name without seeing across apps.
Outage diagnosis
Two deaf containers: check network inspect on both sides — nine times out of ten, they do not share the same network.
Refusing to publish the database
« To test »: no — test from the web with exec and ping, the database stays closed to the outside. Dangerous habit refused.
✓ Best practices
- One network per application, clearly named.
- Publish only the frontend.
- Reach by name, never by IP.
✗ Common pitfalls
- Staying on the default bridge (no DNS).
- Publishing the database « to test » then forgetting it.
- Hard-coding IPs in the config.
Key takeaways
- The dedicated network enables DNS by name.
- Database internal, published frontend: the rule.
- inspect and ping prove the wiring.
- Compose will reuse this pattern automatically.
48h challenge — apply tomorrow
Create monapp, plug bdd (no -p) and web (8080:80) into it, then ping bdd by name from web. Check with network inspect who is plugged where.
- I create a dedicated network per application.
- I publish only the frontend, the database stays internal.
- I reach services by name and prove with ping.
Frequently asked questions
Why can't two containers see each other?
Often they do not share the same network, or you try an IP instead of the name. Check network inspect on both sides, then reach the --name.
One network per container?
No: one network per application (web + database + cache together). Separate by app, not by service.
On a dedicated network, how should the web reach the database named 'bdd'?