Practice brief

Advanced Networking Exercises

In Module 8 you connected the API and the database on a single network. In Module 9 you add a second network to separate traffic. The API gets two network interfaces — one that faces the database, and one that faces the frontend. The database gets only one, and it never touches the frontend network.

Build from scratch

9.1 Build from scratch
~25-35 min

Separate the Database from the Frontend Network

In Module 8 everything ran on a single network, taskflow-net. That is fine for two containers, but in a real application the database should not be reachable from the frontend — it should only be accessible to the API. In this exercise you will create two networks: taskflow-backend for the API and the database, and taskflow-frontend for anything facing users. The API joins both. The database joins only the backend. After this, a container on the frontend network cannot reach the database by name.

Try it yourself first. Open the guided path if you get blocked.

Step 1 — Remove containers from Module 8

docker rm -f taskflow-api taskflow-db
docker network rm taskflow-net

Clean up the single-network setup from Module 8 before building the two-network topology. docker network rm removes the network. If the command says the network has active endpoints, make sure both containers are removed first.

Step 2 — Create the two networks

docker network create taskflow-backend
docker network create taskflow-frontend

Two separate bridge networks. taskflow-backend is for internal communication between the API and the database. taskflow-frontend is for traffic that touches the outside world. Run docker network ls to confirm both appear.

Step 3 — Start the database on the backend network only

docker run -d --name taskflow-db --network taskflow-backend -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=taskflow postgres:16-alpine

The database gets only one network: taskflow-backend. It will never see the frontend network. This is the isolation you want — the database is reachable by the API but not by anything on the frontend side.

Step 4 — Start the API on the backend network

docker run -d --name taskflow-api --network taskflow-backend -p 8000:8000 -e DATABASE_URL=postgres://postgres:secret@taskflow-db:5432/taskflow taskflow-api

The API starts on taskflow-backend so it can reach taskflow-db by name. In the next step you will connect it to taskflow-frontend as well. A container can be connected to multiple networks — it gets a separate network interface for each one.

Step 5 — Connect the API to the frontend network too

docker network connect taskflow-frontend taskflow-api

docker network connect attaches a running container to an additional network without restarting it. After this, taskflow-api has two network interfaces: one for taskflow-backend and one for taskflow-frontend. Run docker inspect taskflow-api and look at the Networks section to confirm both are listed.

Step 6 — Prove the database is not reachable from the frontend network

docker run --rm --network taskflow-frontend alpine ping -c 2 taskflow-db

This starts a temporary Alpine container on the frontend network and tries to ping taskflow-db. It should fail — taskflow-db is not on the frontend network, so Docker's DNS will not resolve the name. This is the isolation you wanted. The --rm flag removes the test container automatically when the command finishes.

Break-fix

9.2 Break-fix
~15-25 min

The API That Cannot Reach Its Database

A teammate created two networks and started both containers, but the API is logging connection refused every few seconds and the /tasks endpoint returns 500. The database is running. The API is running. The DATABASE_URL looks correct. But they forgot one step that determines whether the API can actually reach the database. Reproduce the failure and fix it.

docker rm -f taskflow-api taskflow-db
docker network create taskflow-backend
docker network create taskflow-frontend
docker run -d --name taskflow-db --network taskflow-backend -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=taskflow postgres:16-alpine
docker run -d --name taskflow-api --network taskflow-frontend -p 8000:8000 -e DATABASE_URL=postgres://postgres:secret@taskflow-db:5432/taskflow taskflow-api
docker logs taskflow-api
Show investigative hints
  • Look at which network each container is on. docker inspect taskflow-api and docker inspect taskflow-db both have a Networks section. Compare them.
  • The API needs to be on the same network as the database to communicate with it by name. Being on a different network means no shared DNS — taskflow-db does not resolve.
  • You do not need to remove and re-create the containers. There is a docker command that connects a running container to an additional network.
Show diagnosis and fix rationale

The database is on taskflow-backend, while the API was started only on taskflow-frontend. Those networks are isolated from each other, so the API cannot resolve or reach taskflow-db. Connect the running API container to the backend network with docker network connect taskflow-backend taskflow-api, then verify name resolution and the API endpoint.