KAHIBARO
Discord Login Register

21.9. Networks

Why Docker Networks Matter

When you run several containers, they need a way to talk to each other securely and predictably. Docker networks provide that communication layer.

Without understanding networks, you will often see confusing errors like "connection refused" or "host not found" when containers try to talk to databases, caches, or other services.

In this chapter you will learn how Docker networking works in practice, and how to connect your backend services in a clean way.


Docker Networking Basics

Docker creates and manages its own virtual networks on your host machine. Containers attach to these networks. Inside a network, containers can talk to each other using container names, similar to using hostnames.

You can see existing networks with:

bash
docker network ls

Example output:

NETWORK IDNAMEDRIVERSCOPE
123abc...bridgebridgelocal
456def...hosthostlocal
789ghi...nonenulllocal

The important parts for now:

Default Network Drivers

Docker includes several built-in network drivers. The main ones you will use:

DriverDescriptionTypical Use Case
bridgePrivate network on the host, NAT to the outside worldDefault for single host apps
hostContainer shares the host network stackPerformance or special network needs
noneNo network at allSecurity isolation, one-off tasks
overlayMulti-host networking (with Swarm)Distributed apps across multiple Docker hosts

For most backend development on a single server, bridge networks are what you need.


Bridge Networks in Practice

A bridge network is a private virtual network on the host. Containers on the same bridge network:

Docker automatically creates a default bridge network named bridge, but best practice is to create your own user-defined bridge networks.

Important rule:
Use user-defined bridge networks, not the default bridge, when you want containers to discover each other by name and communicate reliably.

Create a user-defined bridge network:

bash
docker network create myapp-network

Run containers on that network:

bash
docker run -d --name api --network myapp-network myapi-image
docker run -d --name db  --network myapp-network postgres:16

Inside the api container, you can connect to the database using the hostname db, for example:

text
Host: db
Port: 5432

No IP addresses are needed. Docker runs a small DNS server that resolves container names inside the network.


host and none Networks

Although bridge networks cover most use cases, it is useful to know about host and none.

host Network

With the host driver on Linux, the container shares the host’s network stack.

Example:

bash
docker run --network host myapi-image

Effects:

On macOS and Windows, --network host behaves differently due to the extra VM layer, so do not rely on it for production there.

none Network

With the none driver, the container has no network access at all:

bash
docker run --network none myimage

Useful when you want:

Creating and Managing Networks

You already saw docker network create. Here is a small set of common commands.

Creating a Network

bash
docker network create myapp-network

Specify the driver explicitly (optional for bridge):

bash
docker network create --driver bridge myapp-network

Listing Networks

bash
docker network ls

Filter by name:

bash
docker network ls --filter name=myapp

Inspecting a Network

To see details and attached containers:

bash
docker network inspect myapp-network

Key pieces in the output:

Example snippet:

json
"Containers": {
  "c123...": {
    "Name": "api",
    "IPv4Address": "172.20.0.2/16"
  },
  "c456...": {
    "Name": "db",
    "IPv4Address": "172.20.0.3/16"
  }
}

Removing a Network

bash
docker network rm myapp-network

The network must be unused. If containers are still attached, you will get an error. Stop or disconnect containers first.


Connecting Containers to Networks

You can attach a container to a network when starting it, or later.

Connect at Container Creation

bash
docker run -d --name api --network myapp-network myapi-image

If you do not specify --network, Docker uses the default bridge network.

Connect After Container Creation

Attach an existing container:

bash
docker network connect myapp-network api

Now the container api can talk to other containers on myapp-network.

Disconnect a container:

bash
docker network disconnect myapp-network api

The container keeps running, but loses access to that network.


Multiple Networks per Container

A single container can belong to multiple networks. This is useful to separate concerns, for example:

Example:

bash
# Create networks
docker network create frontend-net
docker network create backend-net
# Run database only on backend-net
docker run -d --name db --network backend-net postgres:16
# Run app on backend-net first
docker run -d --name api --network backend-net myapi-image
# Attach app also to frontend-net
docker network connect frontend-net api
# Run reverse proxy only on frontend-net
docker run -d --name nginx --network frontend-net nginx:alpine

Network visibility:

ContainerNetworksCan Reach
dbbackend-netapi
apibackend-net, frontend-netdb, nginx
nginxfrontend-netapi

nginx cannot directly reach db, which is good for security. Only the api container can talk to the database.


Exposing Ports vs Container Networking

A common confusion is the difference between:

Inside a user-defined bridge network:

Example:

bash
docker network create myapp-network
# PostgreSQL listens on 5432 inside the container
docker run -d --name db --network myapp-network postgres:16
# API listens on port 8000 inside the container
docker run -d --name api --network myapp-network myapi-image

Inside api:

The host machine cannot reach either of them yet.

To allow your browser to access the API:

bash
docker run -d --name api \
  --network myapp-network \
  -p 8000:8000 \
  myapi-image

Now:

Key rule:
Use -p HOST:CONTAINER only when you need host or external access.
For container-to-container communication on a user-defined bridge, you do not need to publish ports.


Example: FastAPI + PostgreSQL Network Setup

A realistic backend scenario:

Step 1: Create Network

bash
docker network create backend-net

Step 2: Start PostgreSQL

bash
docker run -d \
  --name db \
  --network backend-net \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=appdb \
  postgres:16

No -p is used, so the database is not exposed to the host or internet.

Step 3: Start FastAPI

bash
docker run -d \
  --name api \
  --network backend-net \
  -p 8000:8000 \
  -e DATABASE_URL="postgresql://appuser:secret@db:5432/appdb" \
  my-fastapi-image

Important parts:

Result:


FromHow to reach APIHow to reach DB
Host machinelocalhost:8000Not accessible directly
api containerhttp://db:5432Using db hostname
Other containers on backend-nethttp://api:8000db:5432

Networks and Docker Compose (Preview)

Another chapter covers Docker Compose in detail, but you will often see networks defined there.

A minimal example:

yaml
version: "3.9"
services:
  api:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
networks:
  default:
    driver: bridge

By default, Compose creates a user-defined bridge network (e.g. projectname_default). Services can reach each other by service name:

You rarely need to think about docker network create explicitly when using Compose, but the concepts are the same.


Troubleshooting Network Issues

Common networking problems and how to reason about them.

"Connection refused"

Possible causes:

Check:

  1. Container status:
bash
   docker ps
   docker logs <container>
  1. Port configuration in the app and Docker run/compose.
  2. Hostname in configuration:
    • From container to container: use container name or service name.
    • From host to container: use localhost:EXPOSED_PORT.

"Name or service not known" / DNS errors

Docker cannot resolve that hostname inside the network.

Typical mistake:

Correct:

Example of wrong vs right connection strings inside a container:


WrongRight
postgresql://user:pass@localhost:5432postgresql://user:pass@db:5432

Summary

These concepts are the foundation for running complete backend stacks in Docker, especially FastAPI + PostgreSQL + Redis setups.

Views: 7

Comments

Please login to add a comment.

Don't have an account? Register now!