Docker
host network mode
published ports
networking
containerization

Docker WARNING Published ports are discarded when using host network mode

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

This Docker warning means you specified both --network host and -p (port publishing) in the same command, and Docker is ignoring the port mapping. Host network mode makes the container share the host's network stack directly, which eliminates the network namespace boundary that port publishing relies on. Since there is no separate container network to map ports into, the -p flag has no effect.

The fix is simple: use either port publishing with bridge networking, or host networking without port publishing. Do not combine both.

How Docker Networking Normally Works (Bridge Mode)

In Docker's default bridge mode, each container gets its own network namespace with its own IP address. Port publishing creates a mapping between a port on the host and a port inside the container.

bash
docker run -d -p 8080:80 nginx

Here Docker sets up a proxy: traffic arriving at the host on port 8080 is forwarded to port 80 inside the container's network namespace. The container's internal port 80 is not directly reachable from outside without this mapping.

text
Host (port 8080) --> Docker proxy --> Container namespace (port 80)

This is the standard model and the one most Docker users are familiar with.

What Host Network Mode Changes

With --network host, Docker does not create a separate network namespace for the container. The container process runs directly on the host's network stack, exactly as if it were a regular host process.

bash
docker run -d --network host nginx

Now Nginx binds to port 80 on the host directly. There is no Docker proxy, no port translation, and no network namespace boundary. The container is the host, from a networking perspective.

text
Host (port 80) <-- Container process binds directly

Because there is no separate namespace, port publishing has nothing to do. That is why Docker prints the warning.

The Warning in Action

This command triggers the warning:

bash
docker run -d --network host -p 8080:80 nginx
# WARNING: Published ports are discarded when using host network mode

Docker creates the container with host networking and ignores the -p 8080:80 flag entirely. Nginx will listen on port 80 on the host, not port 8080.

This catches many developers off guard because they expect the -p flag to remap the port even in host mode. It does not and cannot, because there is no port translation layer in host mode.

Docker Compose Configuration

The same issue appears in Docker Compose:

Incorrect (produces the warning)

yaml
1services:
2  web:
3    image: nginx
4    network_mode: host
5    ports:
6      - "8080:80"

Correct: Bridge with Port Publishing

yaml
1services:
2  web:
3    image: nginx
4    ports:
5      - "8080:80"

Correct: Host Mode Without Ports

yaml
1services:
2  web:
3    image: nginx
4    network_mode: host

In the host mode configuration, Nginx listens on whatever port the Nginx config specifies (default is 80), directly on the host.

When to Use Host Networking

Host networking is not inherently wrong. It exists for specific use cases:

Use CaseWhy Host Mode Helps
Performance-sensitive networkingEliminates the Docker proxy overhead and NAT translation
Service mesh / network agentsAgents that need to see all host traffic (e.g., monitoring, proxies)
Dynamic port bindingApplications that bind many ephemeral ports (e.g., FTP servers, SIP)
Legacy applicationsSoftware that expects to see the host IP and cannot be reconfigured
Host-level service discoveryApplications that register their IP with external systems

For most web applications, APIs, and microservices, bridge mode with explicit port mappings is the better choice.

Bridge vs. Host Comparison

FeatureBridge Mode (default)Host Mode
Network isolationYes (separate namespace)No (shares host namespace)
Port publishing (-p)Works as expectedIgnored (warning printed)
Port conflictsOnly mapped ports conflictAll container ports conflict with host
PerformanceSlight overhead from NATNative performance
SecurityBetter isolationContainer can access host network fully
Cross-platformWorks on Linux, macOS, WindowsFull support on Linux only
Multiple containers on same portPossible (map to different host ports)Not possible (same as running two host processes)

Platform Differences

Host networking behaves differently across platforms:

bash
1# Linux: true host networking, container shares /proc/net with host
2docker run --network host --rm alpine ip addr
3# Shows actual host network interfaces
4
5# macOS (Docker Desktop): host mode runs inside the Linux VM, not the Mac
6docker run --network host --rm alpine ip addr
7# Shows the Docker Desktop VM's interfaces, not the Mac's

On macOS and Windows, Docker runs inside a Linux VM. --network host shares the VM's network, not the physical host's network. This means host mode is less useful on non-Linux platforms, and port forwarding from the VM to the host still happens behind the scenes.

Debugging Network Issues

When you see this warning, verify what port the container is actually using:

bash
1# Check which ports are listening on the host
2ss -tlnp | grep nginx
3# or
4netstat -tlnp | grep nginx
5
6# Check from Docker's perspective
7docker inspect <container-id> --format '{{json .NetworkSettings}}' | python3 -m json.tool

If you are in host mode and the application listens on port 80, you access it at http://localhost:80, not at whatever port you specified with -p.

To confirm the container is using host networking:

bash
docker inspect <container-id> --format '{{.HostConfig.NetworkMode}}'
# Output: host

Changing the Application Port in Host Mode

Since you cannot remap ports with -p in host mode, change the port inside the container instead:

bash
1# Nginx: change the listen port via environment or config
2docker run --network host -e NGINX_PORT=8080 nginx
3
4# Or mount a custom config
5docker run --network host -v ./nginx.conf:/etc/nginx/nginx.conf nginx

For custom applications, pass the port as an environment variable:

bash
docker run --network host -e PORT=8080 my-app

This is the only way to control which port is used when running in host mode.

Common Pitfalls

Expecting -p 8080:80 to work with --network host. This is the exact scenario the warning describes. Port publishing is completely ignored in host mode. The application will bind to whatever port its configuration specifies.

Using host mode as a quick fix for networking problems. When a container cannot reach another service, switching to host mode often "fixes" the issue by eliminating the network boundary entirely. But it also removes isolation and hides the real problem, which is usually a missing Docker network, a wrong hostname, or a firewall rule.

Assuming host networking works the same on macOS and Linux. On macOS, --network host shares the Docker Desktop VM's network, not the Mac's physical network. Port forwarding still goes through the VM, which makes host mode less useful than on a real Linux host.

Port conflicts when running multiple containers. In bridge mode, you can run five containers all listening on internal port 80 and map them to host ports 8080-8084. In host mode, only one process can bind to port 80. This is the same constraint as running multiple non-containerized processes.

Leaving ports in a Compose file alongside network_mode: host. The ports section is silently ignored, which creates a misleading configuration. Future maintainers will assume those port mappings are in effect. Remove the ports section to make the configuration honest.

Not checking the platform when choosing host mode. On Linux servers, host mode delivers real performance benefits. On macOS or Windows developer machines, it often does nothing useful because the container is in a VM anyway. Bridge mode with -p is usually the better choice for local development.

Summary

The warning fires because host networking and port publishing are mutually exclusive concepts. Host mode puts the container directly on the host network with no port translation layer, so -p has no effect. Use bridge mode (the default) when you need port mappings. Use host mode when you need native network performance or direct host network access. Never combine both. In Docker Compose, remove the ports section when using network_mode: host to keep the configuration clear and accurate.


Course illustration
Course illustration

All Rights Reserved.