Skip to content

Host Network Overview


Bridge networking gives a container its own network namespace and connects that namespace to the host through a virtual bridge. That isolation is useful, but it also introduces another layer between the application and the host’s network stack.

What if you don’t want that layer?

Docker’s host network does exactly that: instead of giving the container its own isolated network stack, Docker lets the container share the host’s network namespace.

There is no docker0 bridge sitting between the application and the host network.

That makes host networking faster and simpler in some situations — but you give up a major part of container network isolation in exchange.

The Core Idea

With the default bridge, the model is:

Container
   |
   | own network namespace
   v
virtual interface
   |
   v
docker0
   |
   v
Host network stack

With host networking:

Container
   |
   | shares network namespace
   v
Host network stack

That’s the whole idea.

The container still has its own filesystem, processes, environment, and other isolation mechanisms.

But networking is different:

The container uses the host’s network stack directly.

Start a Container with Host Networking

You select host networking with:

docker container run --network host nginx:alpine

The important part is:

--network host

This tells Docker:

Don’t give this container a separate network namespace. Put it in the host’s network namespace.

You can confirm the container’s network mode with:

docker inspect <container-name>

Look for the network configuration.

You can also list Docker’s built-in networks:

docker network ls

You’ll normally see:

bridge
host
none

The host entry corresponds to Docker’s host network.

The Biggest Difference: There Is No Port Mapping

This is where host networking can feel strange if you’ve just learned bridge networking.

With bridge networking, you might do:

docker container run -d \
  --name web \
  --publish 8080:80 \
  nginx:alpine

The application listens on:

container:80

and Docker publishes it as:

host:8080

Conceptually:

Host :8080
    |
    v
Docker port forwarding
    |
    v
Container :80

With host networking:

docker container run -d \
  --network host \
  nginx:alpine

there is no container-side network namespace to forward traffic into.

The nginx process is listening directly on the host’s network stack.

So if nginx listens on:

host:80

you reach it through:

http://localhost:80

There is no:

--publish 8080:80

involved.

Note

Port publishing is not used with host networking because the container is already sharing the host’s network namespace. There is no separate container network interface that needs a port-forwarding rule.

Think About the Port as Belonging to the Host

This is the mental shift that makes host networking easy to understand.

With bridge networking:

Container A
    |
    +── :80

That port belongs to the container’s network namespace.

With host networking:

Host
    |
    +── :80
          ↑
       container process

The process inside the container is using the host’s network stack.

So if another process on the host is already listening on port 80, your host-networked container can’t simply take it.

They are sharing the same network namespace.

This gives us an important rule:

Host-networked containers and host processes compete for the same network ports.

Why --publish Doesn’t Make Sense Here

Suppose you try:

docker container run -d \
  --network host \
  --publish 8080:80 \
  nginx:alpine

The --publish option doesn’t provide the normal bridge-style port mapping when host networking is used.

Why?

Because there is nothing to map.

The process is already using the host network directly.

Compare the two models:

BRIDGE

Host :8080
    |
    v
port mapping
    |
    v
Container :80

versus:

HOST

Host :80
    |
    v
Container process

The second one has no separate container port that Docker needs to translate.

The Mental Model to Remember

If you remember only one diagram for host networking, remember this:

    flowchart LR
    C["Container<br/>process"] --> H["Host network namespace"]
    H --> I((Network))
  

And compare it with the bridge model:

    flowchart TB
    subgraph Bridge["Bridge networking"]
        C1["Container"] --> V["Virtual interface"]
        V --> D["docker0"]
        D --> H1["Host network stack"]
    end

    subgraph Host["Host networking"]
        C2["Container process"] --> H2["Host network stack"]
    end
  

The critical visual difference is:

Bridge:

Container → virtual interface → docker0 → host network

Host:

Container → host network

Whenever you hear host network, think:

The container is sharing the host’s network namespace.

What Is a Network Namespace?

You’ve already seen the phrase “network namespace” in the bridge explanation, so let’s make the contrast concrete.

A network namespace gives a process its own view of networking.

A container with its own network namespace can have:

its own:
- network interfaces
- IP addresses
- routing table
- network ports

So two containers can both listen on port 80:

Container A
    :80

Container B
    :80

because they have separate network namespaces.

With host networking, that separation disappears:

Host network namespace
       |
       +── :80 ← Container A
       |
       +── :80 ← Container B  ✗

Both processes are trying to use the same host port.

Only one can successfully bind to a particular address and port combination.

This is one of the most important trade-offs of host networking.

What Happens to the Container’s IP?

With bridge networking, you might see something like:

Container
172.17.0.2

That address belongs to the container’s network namespace.

With host networking, there isn’t a separate container IP in the same sense.

The container is using the host’s network interfaces and addresses.

So instead of thinking:

container IP → host IP

think:

container process
       |
       v
host's network interfaces

For example, if the host has:

127.0.0.1
192.168.1.20

the host-networked process is using the host network namespace containing those interfaces.

The exact addresses depend on the host.

Does Host Networking Mean No Isolation at All?

No.

This is an important distinction.

Host networking removes network namespace isolation.

It does not mean the container suddenly becomes the host process in every respect.

The container still has other forms of isolation.

Conceptually:

                 Container
        ┌─────────────────────────┐
        │                         │
        │  Filesystem isolation   │
        │  Process isolation      │
        │  Resource controls      │
        │                         │
        │  Network namespace      │
        │       ↓                 │
        │   shared with host      │
        │                         │
        └─────────────────────────┘

So don’t memorize:

“host network = no isolation.”

Memorize:

host network = no separate network namespace.

That is much more precise.

Why Would Anyone Want This?

At first glance, host networking sounds like a bad deal:

  • You lose network isolation.
  • You lose the normal container port-mapping model.
  • You make containers compete with host processes for ports.

So why use it?

Because sometimes the network isolation layer itself gets in the way.

For example, an application might:

  • need very high network throughput
  • handle a very large number of packets
  • need low network latency
  • work directly with host network interfaces
  • need access to the host’s network namespace
  • be a network monitoring or diagnostic tool

In these situations, avoiding Docker’s virtual networking layer can be useful.

The exact performance benefit depends on the workload and platform, so host networking should not be treated as a magical “make networking faster” switch.

The important trade-off is:

More network isolation
        ↓
bridge networking

Less network isolation
        ↓
host networking

Host Networking Removes the Bridge Path

This is another useful comparison with what you learned earlier.

Bridge

    flowchart LR
    C["Container"] --> V["Virtual interface"]
    V --> B["docker0"]
    B --> H["Host network stack"]
    H --> N["NAT / routing"]
    N --> I((Network))
  

There are several pieces involved.

Host

    flowchart LR
    C["Container process"] --> H["Host network stack"]
    H --> I((Network))
  

The container’s process is already inside the host’s network namespace.

There is no docker0 bridge between the process and the host network.

That is the key architectural difference.

What About Container-to-Container Communication?

This is another place where host networking differs from user-defined bridge networking.

With a user-defined bridge, you could have:

web ── app-net ──> backend
        |
        └── Docker DNS

and the application could use:

http://backend

Host networking does not provide that same user-defined-network model.

The containers are sharing the host’s network namespace rather than joining a private bridge network.

So if two host-networked containers need to communicate, think in terms of the host’s network:

Host network
     |
     +── process A :8000
     |
     +── process B :9000

They communicate using addresses and ports available through that shared network namespace.

The convenient Docker-network DNS model from user-defined bridges is not the thing to reach for here.

The Port Collision Problem

Let’s make the trade-off concrete.

Suppose you start:

docker container run -d \
  --name server-a \
  --network host \
  nginx:alpine

Suppose nginx listens on port 80.

Now start another:

docker container run -d \
  --name server-b \
  --network host \
  nginx:alpine

Both containers are trying to use the host’s port 80.

That’s a conflict.

With bridge networking, you could have:

container A :80 → host :8080
container B :80 → host :8081

because each container has its own network namespace.

With host networking, both processes see the same host network:

server-a ──┐
           ├── host :80
server-b ──┘

They cannot both claim the same port.

This is a practical consequence of giving up network namespace isolation.

Host Networking and localhost

localhost becomes particularly interesting here.

With bridge networking, inside a container:

localhost

means:

This container’s own network namespace.

It does not mean the Docker host.

With host networking:

localhost

refers to the shared host network namespace.

So a host-networked container and a host process can both use:

localhost

to refer to the same network namespace.

This is another good mental check:

Bridge container:

localhost
   ↓
container itself


Host-networked container:

localhost
   ↓
shared host network namespace

That difference can matter for applications that communicate with services bound to loopback.

Host Networking Is Not the Same as Host Mode for Everything

The word “host” can be misleading.

When you write:

--network host

you are selecting the network mode.

You are not saying:

"remove all container isolation"

or:

"run this as a normal host process"

The container is still a container.

Only its network namespace is shared with the host.

When Should You Reach for Host Networking?

A useful decision rule is:

Do I want normal container network isolation?
        |
       Yes
        |
        v
User-defined bridge

Do I specifically need the host's network namespace?
        |
       Yes
        |
        v
Host networking

For ordinary multi-container applications, bridge networking is usually the natural choice.

For workloads where direct access to the host network is important, host networking can be appropriate.

Don’t choose host networking simply because the command is shorter.

Choose it because you actually want the trade-off.

Bridge vs Host

Now put the two models side by side:

ScopeBridgeHost
Network namespaceSeparateShared with host
Container gets its own network stackYesNo
docker0 involvedYes, for the default bridgeNo
Container IPSeparate private IPUses host network
Port publishingCommonly usedNot used in the normal bridge sense
Port isolation between containersYesNo
Docker DNS on user-defined networkYesNot the model
Network isolationStrongerWeaker
Typical useNormal applicationsSpecialized network workloads

The trade-off is simple:

Bridge
  ↓
Isolation + Docker networking features

Host
  ↓
Direct access to host networking

The One Diagram to Remember

If the bridge diagram from the previous lessons represents:

Container
    ↓
docker0
    ↓
Host

then host networking should immediately trigger this picture:

             Docker Host
┌────────────────────────────────┐
│                                │
│   Host network namespace       │
│                                │
│   ┌────────────────────────┐   │
│   │ Container process      │   │
│   │                        │   │
│   │ uses host networking   │   │
│   └────────────────────────┘   │
│                                │
│   Host processes               │
│                                │
└────────────────────────────────┘

There is no:

container → docker0 → host

Instead:

container process
       ↓
host network namespace

That’s host networking in one picture.

What’s Next

We’ve seen the theory and the trade-off: host networking removes the container’s separate network namespace and puts its network activity directly into the host’s network stack.

Now we’ll use it for a concrete problem.

We’ll run a container using --network host, see how its ports behave differently from a bridge-networked container, and compare the result with the bridge example from the previous lesson.

That hands-on example is where the difference between “container port” and “host port” becomes impossible to miss.

Last updated on