What's the difference between docker BRIDGE and HOST modes?

According to the docker documentation about bridge networking:

In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network.

According to the docker documentation about host networking

If you use the host network driver for a container, that container’s network stack is not isolated from the Docker host. For instance, if you run a container which binds to port 80 and you use host networking, the container’s application will be available on port 80 on the host’s IP address.

If you want to deploy multiple containers connected between them with a private internal network use bridge networking. If you want to deploy a container connected to the same network stack as the host (and access the same networks as the host) use host networking. If you simply want to publish some ports, run the container with the --publish or -p option, such as -p 8080:80.


In your first example I'd expect the application to be reachable on the host's IP address at port 8000 (the remapped port), and in the second port 5000 (there is no remapping option with host networking). If there's some sort of configuration or firewalling issue preventing this from working you should address that, rather than hack around it with --net host.


Bridge networking is Docker's standard networking mode. You should prefer it if at all possible. There are, confusingly, two different modes of it, but the form you show with an explicit docker network create is a best practice and you should use it if at all possible. Host networking completely disables Docker's network isolation. It means containers see and use exactly the same network interfaces the host has available, without an intermediate NAT layer.

With bridge networking, you need the docker run -p option to make specific ports visible outside of Docker. As an operator you can remap ports, bind to specific interfaces on a multi-homed system, or simply decline to make a service visible to other hosts at all. The explicit docker network create form lets containers connect to each other using their docker run --name as host names. If you're running multiple application stacks on the same host, they can be partially isolated from each other by using separate networks. Each container has its own separate network space, and localhost means "this container". This mode is also an easy step to the networking models in multi-host systems like Docker Swarm or Kubernetes.

With host networking, none of the above works at all; you cannot use docker run --net host -p ... and you have no choice about where or how ports are exposed. You can't reach other containers, unless they're configured to publish ports themselves. Since you're using the host's network, localhost means the host's view of itself.

For all that it's frequently recommended in SO answers, --net host is rarely necessary. The two cases I can think of off hand are for a service that needs to interrogate the host's network stack (for instance, a service-discovery system like Consul needs to know every port the host is listening on to advertise that) or for a service that has a large or inconsistent set of ports it uses. If you're using --net host because you've hard-coded localhost in your application, you're better off making that configurable..