- Published at
Docker Networking: A Guide for Developers
Table of Contents
- What is a Docker Network?
- Core Properties of Docker Networks
- How Containers Communicate in a Network
- Inside a Network: Internal Ports
- Example:
- DNS and Service Names
- Container Names
- Aliases
- Multi-Container Setup
- Exposing Services with Port Forwarding
- How Port Forwarding Works
- Internal vs. External Ports
- In Docker Compose
- Understanding Internal and External Access
- Internal Access
- External Access
- Bringing It All Together: A Practical Example
- Scenario:
- Steps:
- Key Takeaways
Docker networking is a foundational concept for building and deploying containerized applications. It allows containers to communicate with each other, the host machine, and external networks like the internet. While tools like docker-compose
simplify multi-container setups, they often abstract key networking details that developers need to understand for debugging and configuration.
This guide builds a step-by-step understanding of Docker networking, focusing on DNS, aliases, port forwarding, and internal/external container communication. By the end, you’ll grasp how Docker networks work and avoid common pitfalls.
What is a Docker Network?
A Docker network is a virtual layer that connects containers, enabling communication within a network. Each container in a network has its own unique IP address and is configured to work seamlessly with other containers on the same network. Docker abstracts away much of the complexity, but understanding its principles is crucial for effective application design.
Core Properties of Docker Networks
- Container Communication: Containers on the same network can communicate directly using:
- The container’s IP address (assigned by Docker).
- The container’s name or alias, resolved via Docker’s built-in DNS system.
- Port Exposure: Containers do not expose their services to the host or external networks by default. You must explicitly forward ports for external access.
- DNS Integration: Containers in the same network can resolve each other by name or alias, making service discovery simple.
How Containers Communicate in a Network
When containers are on the same Docker network, they can directly connect to each other using internal ports. These ports correspond to the services running inside the container.
Inside a Network: Internal Ports
For containers within the same network:
- Communication happens directly via the port the application is running on inside the container.
- Port mappings like
-p 8080:3000
are irrelevant for internal communication—these mappings are only for external traffic.
Example:
If a container app
is running a service on port 3000
:
- Another container on the same network can connect to it using
app:3000
. - The external mapping (e.g.,
-p 8080:3000
) is not needed for this internal communication.
DNS and Service Names
Docker provides an internal DNS system for each network, allowing containers to resolve each other by their names or aliases.
Container Names
- A container’s name is its default DNS hostname.
- For example, if a container is named
db
, another container in the same network can connect to it usingdb
as the hostname.
Aliases
- Aliases are additional names for a container within a network. They allow flexibility when naming containers.
- For instance:
Here:docker run --network my-network --name db --network-alias primary-db mydatabase
- The container is reachable as
db
(default name). - It is also reachable as
primary-db
(alias).
- The container is reachable as
Multi-Container Setup
Tools like docker-compose
automatically create service names as DNS entries. For example:
services:
app:
image: myapp
db:
image: mydatabase
- The
app
container can connect to thedb
container by simply usingdb:5432
, assuming the database runs on port5432
.
Exposing Services with Port Forwarding
Docker uses port forwarding to expose container services to the host machine or external networks. This is necessary when you want to access a service running in a container from outside the Docker network.
How Port Forwarding Works
When forwarding a port, you map a container’s internal port to a port on the host:
docker run -p 8080:3000 mywebapp
3000
: The port inside the container where the application is running.8080
: The port on the host machine where the service is exposed.
Requests to http://localhost:8080
are forwarded to port 3000
inside the container.
Internal vs. External Ports
- Internal container communication uses internal ports (e.g.,
3000
). - External systems use the host-mapped port (e.g.,
8080
).
In Docker Compose
Port mappings in docker-compose.yml
are specified as follows:
services:
web:
build: .
ports:
- "8080:3000"
- This maps port
3000
inside theweb
container to port8080
on the host. - Other containers in the same network still access the
web
container using its internal port (3000
).
Understanding Internal and External Access
Internal Access
Containers on the same network communicate directly using the container’s name (or alias) and the port the service listens on inside the container. For example:
- A web server in
webapp
listening on3000
is accessed aswebapp:3000
by another container.
External Access
To make a container’s service accessible to the host or the internet:
- Map the container’s port to a host port (e.g.,
-p 8080:3000
). - Access the service through the host’s port (e.g.,
http://localhost:8080
).
Bringing It All Together: A Practical Example
Let’s walk through a multi-container application where a web app communicates with a database.
Scenario:
- The web app listens on port
5000
. - The database listens on port
5432
.
Steps:
-
Create a Docker network:
docker network create my-app-network
-
Start the database container:
docker run --network my-app-network --name db --network-alias primary-db mydatabase
- Accessible as
db:5432
(container name). - Also accessible as
primary-db:5432
(alias).
- Accessible as
-
Start the web app container:
docker run --network my-app-network --name webapp mywebapp
-
Communication:
- The web app connects to the database using
db:5432
orprimary-db:5432
.
- The web app connects to the database using
-
Expose the web app to the host:
docker run -p 8080:5000 --network my-app-network --name webapp mywebapp
- External users access the web app at
http://localhost:8080
.
- External users access the web app at
Key Takeaways
- Internal Ports Matter: Inside a network, containers communicate using the port the application runs on inside the container (e.g.,
3000
), not the mapped host port. - DNS Simplifies Communication: Containers in the same network can use names or aliases to resolve each other, thanks to Docker’s DNS.
- Port Mappings Are for External Access: Host-to-container or internet-to-container communication requires port forwarding (e.g.,
8080:3000
). - Service Names in Compose: In
docker-compose
, service names automatically act as DNS entries for internal communication.
With these principles in mind, you’ll have the tools to confidently configure and debug Docker networks in any containerized application.
- Name
- Yar Kravtsov
- About
- Senior Software Engineer
- @yarlson