Containerization with Docker

Chapter 6
Docker Networking and Service Connectivity

Diploma in DevOps
Containerization with Docker   •   Diploma

Docker Networking and Service Connectivity

Introduction

Containers are useful only when they can communicate with the services, users, and infrastructure that support an application. Docker networking provides the logical and technical mechanisms for that communication. It determines how containers obtain addresses, how packets move between containers and external systems, how services are discovered, and where communication is intentionally blocked.

For a DevOps practitioner, networking is more than publishing a port. A reliable design must answer several questions: Which containers should communicate? Which interfaces should be exposed to users? Should a service be reachable from the host, from another container, or from another machine? How will a container locate a changing service address? What evidence will identify whether a failure is caused by DNS, routing, a firewall, an application listener, or a container configuration?

This chapter examines Docker bridge, host, overlay, and custom networks; port publishing; embedded DNS; network isolation; and a systematic method for diagnosing connectivity problems.

Learning Objectives

By the end of this chapter, you should be able to:

  • distinguish Docker network drivers and select an appropriate driver;
  • create and inspect custom bridge networks;
  • explain container-to-container communication and DNS-based discovery;
  • publish ports safely to host interfaces;
  • describe host and overlay networking and their limitations;
  • apply network isolation using network membership and service design;
  • troubleshoot connectivity systematically using Docker and operating-system tools; and
  • evaluate networking decisions in a production DevOps context.

1. Networking as an Application Dependency

A typical web application contains several communication paths:

  1. A client connects to a reverse proxy or web server.
  2. The web server connects to an application service.
  3. The application connects to a database, cache, or message broker.
  4. Monitoring and logging systems collect operational data.

These paths should not all have the same exposure. A reverse proxy may need a published host port, while a database should normally be reachable only on an internal application network. Docker networks make this topology explicit.

A container has its own network namespace, including interfaces, routes, and ports. Docker connects that namespace to one or more Docker networks. The container’s process listens on a port inside the namespace; reachability from outside depends on the network driver and whether a port is published.

The distinction between an exposed port and a published port is important. An image instruction such as EXPOSE 8080 documents that the application expects port 8080; it does not make that port reachable from the host. Publishing, for example -p 8080:8080, creates host-side forwarding to the container port.

2. Docker Network Drivers

Docker supports several network drivers. A driver determines how interfaces, addresses, routing, and isolation are implemented.

DriverMain scopeTypical useImportant characteristic
bridgeOne Docker hostLocal multi-container applicationsVirtual network on one host
hostHost network namespacePerformance-sensitive or host-integrated servicesContainer shares host networking
overlayMultiple Docker hostsDocker Swarm servicesRequires a multi-host control/data-plane design
noneContainer onlySpecial isolation or custom networkingNo normal network connectivity
macvlanLocal network segmentLegacy or network-visible workloadsContainer can appear as a network device

The default bridge network is convenient for simple experiments, but user-defined bridge networks are preferable for applications because they provide better isolation, automatic DNS-based discovery, and easier lifecycle management.

2.1 The Bridge Network

A bridge network is a software switch on a Docker host. Containers attached to it receive addresses from a private subnet and can communicate through virtual Ethernet interfaces. The host generally performs forwarding and, when necessary, network address translation (NAT).

A simple command is:

docker network create app-net
docker run -d --name web --network app-net nginx
docker run --rm --network app-net curlimages/curl http://web

In this example, web is a DNS name on the user-defined network. The client does not need to know the container’s current IP address. If the container is recreated, its address may change, but the service name remains stable.

A container can be connected to more than one network:

docker network connect monitoring-net web
docker network disconnect monitoring-net web

This capability is useful for controlled mediation. For example, an application may join an application network and a monitoring network, while the database joins only the application network.

2.2 Host Networking

With host networking, the container uses the host’s network namespace rather than receiving an independent container network interface. On Linux, a process listening on port 8080 in the container is listening on the host’s port 8080. Port publishing is generally unnecessary and may be ignored because there is no separate container address to forward to.

Host mode can reduce networking overhead and is sometimes useful for network agents or applications that must observe host interfaces. However, it weakens isolation: port conflicts are possible, and the container gains closer access to host networking. Platform support and behavior differ, especially outside native Linux environments. It should therefore be selected deliberately rather than used as a default solution to connectivity problems.

2.3 Overlay Networking

An overlay network creates logical connectivity across multiple Docker hosts. It is associated primarily with Docker Swarm services and depends on host-to-host communication, control-plane coordination, and appropriate firewall rules. An overlay is not simply a bridge network stretched magically across the internet.

For overlay networking to work reliably, nodes must be able to communicate using the ports and protocols required by the selected Docker deployment. The exact requirements depend on the operating system, Docker version, encryption settings, and control-plane design. In production, these requirements must be verified against current vendor documentation and security policy.

Overlay networks support service-oriented deployment: a service can have multiple replicas distributed across nodes, while clients use a service name rather than a particular task IP. This is valuable for resilient distributed applications, but it introduces additional failure domains, including node availability, cluster membership, and cross-host firewall configuration.

2.4 Custom Networks

A custom network is a deliberately named network created for a specific application or trust boundary. For example:

docker network create --driver bridge backend-net
docker network create --driver bridge frontend-net

A database can be attached only to backend-net; a reverse proxy can join both networks. This produces a controlled path:

Client → reverse proxy → application → database

The database is not directly reachable by clients that are connected only to frontend-net. This is network segmentation, not a replacement for authentication or encryption. A compromised container with access to a shared network may still attempt to connect to other services, so application-level controls remain necessary.

3. Addressing, Ports, and Port Publishing

An IP address identifies a network interface, while a port identifies an application endpoint on that interface. A connection is commonly described by a protocol, destination IP address, and destination port. TCP and UDP are separate transport protocols; a TCP listener on port 53 is not the same endpoint as a UDP listener on port 53.

A container port exists inside the container’s network namespace. Publishing creates a host-facing mapping:

docker run -d --name api -p 127.0.0.1:8080:8080 my-api:1.0

The general form is:

-p [host-IP:]host-port:container-port[/protocol]

The protocol defaults to TCP when omitted. The preceding command binds host port 8080 only to loopback. It is therefore suitable for a service intended for local development or access through a host-resident reverse proxy. By contrast:

docker run -d -p 8080:8080 my-api:1.0

usually binds on all host interfaces, subject to Docker and operating-system behavior. This may expose the service to other reachable machines and should be treated as a security decision.

Publishing does not change the port on which the application listens inside the container. For example, -p 9000:8080 means clients use host port 9000, while the application must listen on container port 8080.

A common failure occurs when the application binds only to 127.0.0.1 inside the container. In that case, it accepts connections only from the container’s own loopback interface. For a service intended to receive connections through its container interface, the application commonly needs to bind to 0.0.0.0 inside the container, while host exposure is still controlled by publishing and firewall policy. The correct binding depends on the application and security design; it should not be changed blindly.

4. Docker DNS and Service Discovery

User-defined Docker networks provide an embedded DNS service. Containers can normally resolve the names of other containers on the same network. In a Compose project, service names commonly become discoverable names. For example:

services:
  api:
    image: example/api:1.0
    networks: [app]
  db:
    image: postgres:16
    networks: [app]

networks:
  app:

The API should connect to the database using the hostname db, not localhost. Inside the API container, localhost refers to the API container itself. This is one of the most important conceptual distinctions in container networking.

DNS-based discovery avoids hard-coding ephemeral container IP addresses. It also supports replacement and scaling better than static address configuration. Nevertheless, DNS does not guarantee that a service is ready to accept connections. Name resolution can succeed while the database is still starting, so applications need retry logic, health checks, and suitable startup behavior.

Aliases can provide an additional stable name:

docker network connect --alias database app-net db

DNS scope is significant. A container connected to frontend-net cannot normally resolve a container that exists only on backend-net. If a service is attached to multiple networks, its connectivity and name resolution must be considered on each network.

5. Isolation and Security Boundaries

Network isolation should reflect communication requirements. A practical pattern is:

  • public edge network: reverse proxy and public-facing components;
  • application network: reverse proxy, application services, and possibly workers;
  • data network: application services and databases;
  • operations network: monitoring, metrics, and administrative tools.

A reverse proxy may be attached to both the edge and application networks. A database should usually be attached only to the data network. This limits accidental exposure and reduces the number of possible attack paths.

Isolation is layered. Docker network membership is one control, but it does not replace:

  • service authentication and authorization;
  • TLS where data requires confidentiality or integrity;
  • host firewalls and cloud security groups;
  • least-privilege container and process settings;
  • secret management;
  • image and dependency scanning; and
  • logging and monitoring.

Do not treat an internal Docker network as automatically trusted. A network-connected service may still be attacked by another compromised workload. Production designs should also consider egress controls, DNS security, credential rotation, and segmentation between development, testing, and production environments.

6. A Systematic Connectivity Troubleshooting Method

Troubleshooting should proceed from the lowest relevant layer to the highest. Avoid changing several variables at once.

Step 1: State the intended path

Write the source, destination, protocol, and port. For example:

api container → db container, TCP port 5432, on backend-net

Also clarify whether the test originates inside a container, on the Docker host, or on a remote client.

Step 2: Verify container and network state

docker ps
docker inspect api
docker network ls
docker network inspect backend-net

Check that both containers are running, attached to the expected network, and assigned appropriate addresses. Inspect published ports with docker port api.

Step 3: Test name resolution

From a diagnostic container on the same network:

docker run --rm --network backend-net busybox nslookup db

If the name cannot be resolved, investigate network membership, the name or alias, embedded DNS behavior, and container configuration before investigating the application.

Step 4: Test transport reachability

Use a suitable client:

docker run --rm --network backend-net curlimages/curl \
  curl -v http://api:8080/health

For a raw TCP test, tools such as nc may be appropriate when available. A successful DNS lookup does not prove that the destination port is open.

Step 5: Check the listener and application logs

docker exec api ss -lnt

docker logs api

Confirm that the process is listening on the expected address and port. A listener on 127.0.0.1 may reject connections arriving through the container interface. Also check application readiness, credentials, protocol mismatches, and startup errors.

Step 6: Check host publication and external controls

For host-to-container or remote-client tests, inspect the publishing rule, host firewall, cloud security group, load balancer, and routing path. Test locally on the host first, then from an appropriate remote client. A service working from the host but not remotely often indicates an exposure or firewall issue rather than a container application issue.

Symptom-based interpretation

SymptomLikely area to inspect
Name does not resolveNetwork membership, service name, DNS scope
Name resolves but connection is refusedNo listener, wrong port, application not ready
Connection times outFirewall, routing, wrong address, dropped packets
Works inside container but not from hostPublishing, host binding, firewall
Works by IP but not by nameDNS or alias configuration
Works on one network but not anotherNetwork attachment or segmentation policy
Intermittent connection failuresReadiness, replicas, stale clients, resource or node failure

A disciplined workflow reduces guesswork and creates an auditable record of what was tested.

7. Worked Application: A Three-Tier Compose Design

Consider an illustrative online-bookstore deployment containing a reverse proxy, an API, and a PostgreSQL database. The proxy must be reachable by users. The API must be reachable by the proxy. The database must be reachable by the API but not published to the host.

services:
  proxy:
    image: nginx:1.27
    ports:
      - "127.0.0.1:8080:80"
    networks:
      - edge
      - app
    depends_on:
      - api

  api:
    image: example/book-api:2.0
    networks:
      - app
      - data
    environment:
      DB_HOST: db
      DB_PORT: "5432"
    depends_on:
      - db

  db:
    image: postgres:16
    networks:
      - data
    volumes:
      - db-data:/var/lib/postgresql/data

networks:
  edge:
  app:
  data:

volumes:
  db-data:

Analysis

The proxy is attached to edge and app, allowing it to receive published traffic and contact the API. The API is attached to app and data, allowing it to receive proxy traffic and contact db. The database is attached only to data, so it has no direct path to the proxy or external clients through this Compose topology.

The API uses db as its database hostname because Compose supplies service-name discovery on the shared data network. It does not use localhost. The database port is not published because publication is unnecessary for API-to-database traffic.

The 127.0.0.1 binding makes the proxy accessible only from the Docker host. In a production deployment, a host-level reverse proxy, load balancer, or deliberate non-loopback binding could be used, together with firewall and TLS policy.

Operational refinement

depends_on expresses startup ordering in common Compose configurations; it does not by itself prove that a dependency is ready. Production-quality services should implement health checks and connection retries. Database credentials should be supplied through an appropriate secret mechanism rather than casually embedded in source-controlled configuration.

8. Limitations and Contemporary Practice

Docker networking abstracts substantial complexity, but abstraction can conceal important behavior. Performance may be affected by NAT, encryption, cross-host encapsulation, DNS delays, and host resource contention. Overlay networks introduce operational dependencies between nodes. Host mode reduces isolation. Macvlan can complicate host-to-container communication and may be restricted by physical or virtual network infrastructure.

Modern deployments frequently use Docker Compose for single-host application environments and an orchestrator such as Kubernetes for larger multi-node systems. Kubernetes introduces its own service, DNS, network-policy, and ingress abstractions; Docker networking concepts remain useful, but commands and implementation details differ. Engineers should avoid assuming that a Docker Compose network and a Kubernetes Service are interchangeable concepts.

Observability is increasingly important. Network metrics, flow logs, distributed tracing, DNS monitoring, and container health signals can distinguish application failure from infrastructure failure. Automated tests should verify both intended reachability and prohibited reachability—for example, that the API can reach the database while an edge-only diagnostic container cannot.

9. Professional Best Practices

  1. Prefer named user-defined networks over the default bridge for application systems.
  2. Publish only ports that external clients genuinely require.
  3. Bind development-only services to loopback where appropriate.
  4. Use service names rather than container IP addresses.
  5. Separate public, application, data, and operations traffic when justified.
  6. Treat network membership as one layer of security, not the entire security model.
  7. Make application readiness explicit through health checks and retry behavior.
  8. Document network purpose, allowed paths, published ports, and ownership.
  9. Test connectivity from the same network context as the failing workload.
  10. Review changes to firewall rules, overlay requirements, and exposed interfaces through change management.
  11. Remove unused networks, published ports, aliases, and administrative access.
  12. Record diagnostic evidence before restarting or recreating workloads.

Chapter Summary

Docker networking provides the connectivity model through which containers communicate with one another, the host, and external clients. Bridge networks are appropriate for most single-host applications, while user-defined bridges provide named isolation and embedded DNS. Host networking shares the host’s network namespace and offers lower isolation. Overlay networking supports multi-host Docker Swarm services but requires coordinated node and firewall configuration.

Port publishing maps a host endpoint to a container endpoint; it is distinct from the image-level EXPOSE instruction. Binding to loopback can restrict access to the host, whereas binding on broader interfaces may expose a service to the network. Containers on a shared user-defined network should discover services by DNS names such as Compose service names, not by unstable IP addresses or localhost.

Effective isolation uses multiple purpose-specific networks, but it must be combined with authentication, encryption, host controls, secret management, and monitoring. Connectivity troubleshooting is most reliable when it proceeds from intended path, network state, and DNS, through transport testing and listener inspection, to publishing, firewalls, and application logs. These practices enable secure, maintainable, and observable containerized systems.

Key Terms

Network driver: Docker component that implements connectivity behavior for a network.

Bridge network: A software-based network connecting containers on one Docker host.

User-defined network: A named Docker network created for deliberate application connectivity and isolation.

Host network: A mode in which a container shares the host’s network namespace.

Overlay network: A logical network that connects workloads across multiple Docker hosts.

Network namespace: An isolated set of interfaces, routes, ports, and related networking resources.

Port publishing: Mapping a host port and address to a container port.

Container port: A port on which a process listens inside a container network namespace.

NAT: Network Address Translation, which rewrites network address information between network contexts.

Embedded DNS: Docker’s internal name-resolution facility for containers on user-defined networks.

Service discovery: Locating a service by a stable logical name rather than a changing address.

Network alias: An additional name by which a container or service can be resolved.

Network segmentation: Dividing workloads into networks with distinct communication boundaries.

Loopback address: An address, such as 127.0.0.1, referring to the local network namespace.

Readiness: The condition that a service is prepared to accept and process requests.

Firewall: A control that permits or blocks network traffic according to policy.

Network namespace isolation: Separation of a process’s interfaces, routes, and ports from other namespaces.

Egress control: Policy governing traffic leaving a workload or network.

Connectivity troubleshooting: A structured process for locating failures in naming, routing, transport, publication, or application behavior.

Review Questions

Short Answer Questions

  1. What is the difference between exposing a container port and publishing a port?
  2. Why is a user-defined bridge network generally preferred to Docker’s default bridge network?
  3. What does localhost refer to when used inside a container?
  4. State one advantage and one limitation of host networking.
  5. Why does successful DNS resolution not prove that an application is ready?

Long Answer Questions

  1. Explain how Docker bridge networking, virtual interfaces, addresses, and port publishing work together.
  2. Compare bridge, host, and overlay networking in terms of scope, isolation, and typical use.
  3. Describe how Docker’s embedded DNS supports service discovery and why IP hard-coding is undesirable.
  4. Design a network segmentation model for a web application, API, database, and monitoring service.
  5. Explain a complete troubleshooting workflow for an API container that cannot connect to a database.

Analytical / Application Questions

  1. A database container resolves successfully by name, but connections to TCP port 5432 time out. Identify at least four tests you would perform and explain what each result would indicate.
  2. A development team publishes PostgreSQL with -p 5432:5432 even though only the API needs access. Analyze the security and operational risks and propose a revised design.
  3. In a Compose deployment, the reverse proxy can reach the API, but the API cannot reach the database after the database container is recreated. Develop a diagnosis and remediation plan that considers network membership, DNS, readiness, credentials, and application retry behavior.

Multiple Choice Questions with Answers

Question 1

Which Docker network driver is normally appropriate for connecting multiple containers on one Docker host with user-defined DNS discovery?

A. Bridge

B. Host

C. Overlay

D. None

Correct Answer: A. Bridge

Question 2

What does -p 9000:8080 normally mean?

A. The application must listen on host port 8080

B. Host port 9000 forwards to container port 8080

C. Container port 9000 forwards to host port 8080

D. Both ports are exposed only through DNS

Correct Answer: B. Host port 9000 forwards to container port 8080

Question 3

Inside an API container, what does the hostname localhost normally identify?

A. The Docker host

B. The database container

C. The API container itself

D. The default bridge gateway only

Correct Answer: C. The API container itself

Question 4

Which feature allows a container to locate another container by a stable logical name on a user-defined network?

A. Embedded DNS

B. Host mode

C. Volume mounting

D. Image layering

Correct Answer: A. Embedded DNS

Question 5

Which design best limits database exposure in a three-tier application?

A. Publish the database port on all host interfaces

B. Attach the database only to the data network and avoid publishing its port

C. Use host networking for every container

D. Place all containers on the default bridge and use IP addresses

Correct Answer: B. Attach the database only to the data network and avoid publishing its port

Question 6

What is a likely explanation if a service name resolves but the TCP connection is refused?

A. DNS is necessarily unavailable

B. The destination has no suitable listener or the application is not ready

C. The container must be using an overlay network

D. The host port must always be changed

Correct Answer: B. The destination has no suitable listener or the application is not ready

Question 7

Which command is most directly useful for viewing the containers attached to a particular Docker network?

A. docker image ls

B. docker volume ls

C. docker network inspect

D. docker history

Correct Answer: C. docker network inspect

Question 8

What is a principal characteristic of host networking?

A. The container receives an isolated virtual subnet in every case

B. The container shares the host’s network namespace

C. It automatically creates multi-host routing

D. It disables all application listeners

Correct Answer: B. The container shares the host’s network namespace

Question 9

Why should applications commonly use service names instead of container IP addresses?

A. Container IP addresses are always public

B. Service names remain useful when containers are recreated and addresses change

C. IP addresses cannot carry TCP traffic

D. Service names eliminate the need for authentication

Correct Answer: B. Service names remain useful when containers are recreated and addresses change

Question 10

Which troubleshooting sequence is most systematic?

A. Restart everything, then change ports repeatedly

B. Test DNS only and assume the application is healthy

C. Define the path, inspect network state, test DNS and transport, inspect listeners, then check publication and firewalls

D. Replace the network driver before collecting evidence

Correct Answer: C. Define the path, inspect network state, test DNS and transport, inspect listeners, then check publication and firewalls

Containerization with Docker
Chapter 6 of 15