DevOpsLesson
DevOpsLesson

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Stay Updated

Get notified about new tutorials and features.

Tutorials

  • What is DevOps?
  • Docker Tutorial
  • Terraform Tutorial
  • CI/CD Pipeline
  • All Tutorials

Roadmaps

  • DevOps Engineer
  • Cloud Engineer
  • SRE Path
  • All Roadmaps

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 DevOpsLesson. All rights reserved.

DOCKERKUBERNETESTERRAFORMAWSCI/CDLINUXGITDEVOPS ROADMAPCLOUD ROADMAPSRE ROADMAPGIT CHEATSHEETDOCKER CHEATSHEETK8S CHEATSHEETTF CHEATSHEETLINUX CHEATSHEETDOCKERFILE LINTERYAML VALIDATORCRON PARSERREGEX TESTER

Docker Tutorial

Introduction to docker
Why Use Docker?
Docker vs Virtual Machines
Installing Docker
Key Docker Concepts
Docker Images
Docker Containers
Writing Dockerfiles
Docker Volumes

Networking Basics

PreviousPrev
Next

Understand Docker's networking model including bridge networks, port publishing, container DNS, and how containers communicate with each other.

Docker Network Types

Docker ships with several built-in network drivers, each suited to a different scenario:

DriverWhat It DoesBest For
bridgePrivate internal network on the hostDefault for standalone containers
hostShares the host's network directlyMaximum performance, no isolation
noneNo networking at allAir-gapped containers
overlayMulti-host networkingDocker Swarm / Kubernetes

The Default Bridge Network

When you run a container without specifying a network, it automatically joins Docker's built-in bridge network:

docker run -d nginx
docker inspect bridge   # See all containers on the default bridge

Containers on the default bridge can reach the internet and each other, but only by IP address. There's no automatic DNS, which means you'd need to hardcode IP addresses to connect containers together. That's fragile and error-prone. That's why user-defined networks exist.

User-Defined Bridge Networks

Creating your own network unlocks automatic DNS between containers, and they can find each other by name instead of IP:

# Create a network
docker network create my-app-network

# Run containers on it
docker run -d --name web   --network my-app-network nginx
docker run -d --name db    --network my-app-network postgres:16
docker run -d --name cache --network my-app-network redis:7

Now from inside the web container, you can reach the others by their container name:

docker exec -it web curl http://cache:6379   # Redis by name
docker exec -it web psql -h db -U postgres  # Postgres by name

Docker's embedded DNS server handles name resolution automatically. No IP addresses needed, no manual config. This is why user-defined networks are always recommended over the default bridge.

Port Publishing

Containers are isolated from your host machine by default. To make a service accessible from your browser, another machine, or a CI pipeline, you need to publish a port. The format is -p HOST_PORT:CONTAINER_PORT.

# Map host port 8080 to container port 80
docker run -d -p 8080:80 nginx

# Bind to localhost only (more secure as it is not accessible from other machines)
docker run -d -p 127.0.0.1:5432:5432 postgres:16

# Publish multiple ports
docker run -d -p 80:80 -p 443:443 nginx

# Let Docker pick a random available host port
docker run -d -p 80 nginx
docker port <container-id>   # Check what port was assigned

A key rule: Only publish ports that need to be reached from outside. Container-to-container traffic on the same network works without any port publishing at all.

# db is internal only so no -p needed
docker run -d --name db --network app-net postgres:16

# web is public
docker run -d --name web --network app-net -p 80:3000 myapp

Managing Networks

# List all networks
docker network ls

# Inspect a network (see connected containers, subnet, gateway)
docker network inspect my-app-network

# See which network(s) a container is on
docker inspect my-container --format='{{json .NetworkSettings.Networks}}' | python3 -m json.tool

# Connect a running container to a network (no restart needed)
docker network connect my-app-network my-container

# Disconnect a container from a network
docker network disconnect my-app-network my-container

# Connect with an alias (extra DNS name)
docker network connect --alias api my-app-network backend-v2

A container can belong to multiple networks at the same time, it is useful when you need one container to bridge two separate networks.

EXPOSE vs -p

These two things sound similar but do very different things:

EXPOSE in Dockerfile-p in docker run
What it doesDocuments which port the app usesActually opens the port to the host
Reachable from host?NoYes
Required for container-to-container?NoNo

EXPOSE is just metadata, a note to developers (and tools like Docker Compose) saying "this container listens on this port." It doesn't open anything. Only -p actually publishes a port.

Host Networking

With --network host, the container skips network isolation entirely and shares the host's network stack directly. The upside is maximum throughput with no NAT overhead. The downside is zero isolation, the container can bind to any host port, which means port conflicts become your problem. Use it sparingly, typically only for performance-critical tools or network monitoring utilities.

docker run -d --network host nginx
# nginx now listens on host port 80, so no -p needed

Custom DNS Options

Within a user-defined network, DNS works automatically. But you can also customize it:

# Use a specific DNS server
docker run --dns 8.8.8.8 --dns 8.8.4.4 my-app

# Add a custom /etc/hosts entry
docker run --add-host db.internal:192.168.1.50 my-app

# Set a DNS search domain
docker run --dns-search company.internal my-app

Quick Reference

CommandWhat It Does
docker network create <name>Create a new bridge network
docker network lsList all networks
docker network inspect <name>See containers and config
docker network connect <net> <c>Add a container to a network
docker network disconnect <net> <c>Remove a container from a network
docker run -p 8080:80Publish port 80 to host port 8080
docker run --network hostUse host networking (no isolation)

Key Takeaways

  • Default bridge network has no DNS: containers can only reach each other by IP, which is fragile; use user-defined networks instead
  • User-defined bridge networks give you automatic DNS: containers find each other by name, no IP addresses needed
  • Only publish ports that need external access: container-to-container traffic on the same network is already routable without -p
  • EXPOSE in a Dockerfile is documentation only: it doesn't open any ports; -p in docker run is what actually publishes
  • --network host removes all isolation: useful for performance-critical tools, but avoid it for regular application containers
  • One container can be on multiple networks: handy when you need a service to bridge two isolated environments

Frequently Asked Questions

Why can't my two containers talk to each other even though they're both running?

They're probably both on the default bridge network, where containers can only communicate by IP address, not by name. Create a user-defined network with docker network create, add both containers to it with --network, and they'll be able to reach each other by container name automatically.

What's the difference between -p 8080:80 and -p 80?

-p 8080:80 maps host port 8080 to container port 80, and you choose the host port. -p 80 tells Docker to map container port 80 to a random available port on the host. Use docker port <container> to see what port was assigned.

Do I need to publish a port for containers on the same network to communicate?

No. Containers on the same user-defined network can reach each other freely without any port publishing. Port publishing is only needed to make a service accessible from outside Docker which means from your browser, another machine, or the host itself.

What does EXPOSE actually do if it doesn't open ports?

It's documentation. It tells anyone reading the Dockerfile what port the application listens on. Some tools (like Docker Compose and Docker Desktop) use it to suggest port mappings. But it has zero effect on actual network accessibility, only -p does that.

Can a container be on more than one network?

Yes. You can connect a running container to additional networks with docker network connect. This is useful when you have a gateway or proxy container that needs to reach services on two separate isolated networks.

What's the difference between bridge and host networking?

Bridge networking gives each container its own isolated network namespace. It has its own IP, and you control what's exposed via port publishing. Host networking removes that isolation completely; the container shares the host's network interfaces and ports directly. Bridge is safer and more flexible; host is faster but requires careful port management.

PreviousPrev
Next

Continue Learning

Lifecycle Management

Control every stage of a container's life including start, stop, restart, pause, kill, and understand the difference between each.

7 min·Easy

Exec & Interact

Shell into running containers, execute one-off commands, copy files, and debug live services with docker exec and docker cp.

8 min·Easy

Logs & Monitoring

Stream, filter, and manage container logs. Monitor resource usage with docker stats. Know what your containers are doing in real time.

7 min·Easy

Explore Related Topics

Ku

Kubernetes Tutorials

Orchestrate your Docker containers at scale

CI

CI/CD Tutorials

Automate Docker builds and deployments in pipelines

Try the Tool

Dockerfile Linter

Instantly lint your Dockerfile for best-practice violations and security issues.

On This Page

Docker Network TypesThe Default Bridge NetworkUser-Defined Bridge NetworksPort PublishingManaging Networks`EXPOSE` vs `-p`Host NetworkingCustom DNS OptionsQuick ReferenceKey TakeawaysFrequently Asked Questions