Docker Networking Explained: Bridge Networks, Ports and DNS

· 3 min read · Docker & Rancher Desktop Tutorials

How containers talk to each other #

Every container gets its own network stack: its own IP address, routing table and ports. Docker connects containers through networks. You rarely need to know IP addresses: containers on the same user-defined network find each other by name.

Docker networking: the browser reaches the web container through a published port, and the web, api and db containers talk to each other by name on a user-defined bridge network, while the database publishes no port
A user-defined bridge network with DNS, and one published port

Network drivers #

Driver What it does
bridge The default. A private virtual network on the Docker host. Containers can reach the outside through NAT.
host The container shares the network of the host: no isolation, no port mapping. Inside Rancher Desktop the "host" is the Linux VM, not your computer.
none No network except loopback.
overlay Connects containers across several hosts (Swarm).
macvlan Gives the container its own MAC address on your physical network.

The default bridge vs a user-defined bridge #

Containers started without --network join the default bridge, where they can reach each other only by IP address. Create your own network and you get automatic DNS, better isolation and the ability to connect and disconnect containers while they run.

$ docker network create app-net
$ docker run -d --name db  --network app-net -e POSTGRES_PASSWORD=secret postgres:17
$ docker run --rm --network app-net postgres:17 \
    psql -h db -U postgres -c "SELECT 'it works' AS result;"

The second container reaches the first one with the hostname db: Docker's embedded DNS resolves container names (and, in Compose, service names) on user-defined networks.

Publishing ports #

Containers are not reachable from outside the network by default. -p (or --publish) maps a port of the host to a port of the container:

$ docker run -d --name web -p 8080:80 nginx:1.27          # all interfaces
$ docker run -d --name web2 -p 127.0.0.1:8081:80 nginx:1.27   # only your computer
$ docker run -d -P nginx:1.27                              # random host port for each EXPOSE
$ docker port web
80/tcp -> 0.0.0.0:8080

Ports below 1024 on Linux #

Rancher Desktop on Linux cannot publish ports below 1024 (such as 80 or 443) unless you allow it:

$ sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80

Add it to /etc/sysctl.d/ to make it permanent.

Connect and inspect #

$ docker network ls
$ docker network inspect app-net            # subnet, gateway and connected containers
$ docker network connect app-net web        # add a running container to a network
$ docker network disconnect app-net web
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

A container can be on several networks. A frequent pattern is a frontend network for the proxy and the app and a backend network for the app and the database, so the proxy can never reach the database.

$ docker network create --internal backend   # no access to the outside world at all

Debugging connectivity #

Most problems are one of these:

  1. "Connection refused" from the host: the port is not published (docker port) or the application listens only on 127.0.0.1 inside the container. Bind it to 0.0.0.0.
  2. Name does not resolve: the containers are not on the same user-defined network. The default bridge has no DNS.
  3. Works with the IP but not with the name: you are on the default bridge.
  4. localhost inside a container: it is the container itself, not your computer. To reach a service on your computer from a container use host.docker.internal (available in Docker Desktop and Rancher Desktop) or the IP of the host.

Use a tool container that shares the network of the failing one:

$ docker run --rm -it --network container:web nicolaka/netshoot
# inside: ping db, nslookup db, curl -v http://api:3000, ss -tlnp

DNS and proxies #

Containers inherit the DNS configuration of the daemon. In a corporate network with a proxy, configure it in the engine and not in every Dockerfile. Rancher Desktop can pass the proxy settings of the host to the VM, and the Windows version supports domain names and wildcards in its no-proxy list. See troubleshooting.

Next steps #

Define networks, volumes and services in one file with Docker Compose.

#Docker #Network