Docker containers are assigned addresses from a network on each host (or from a mesh in the case of a Swarm cluster) when run in a standalone fashion, and in order to access them from outside the host, the following patterns are common:
docker run -d --name nginx -p 8080:80 nginx
to expose the nginx app on http://HOST_IP:8080 , or less commonly, attaching directly to the host’s network:
docker run -d --net host --name nginx nginx
where no port forwarding rule is required, because it will bind ports as required to the host network.
In a production scenario, or even one where a host and its containers should have separate addresses, or not accessed through the host network, docker network can be used to attached to a bridge device, to allow Docker containers to get addresses from your external networks.
In a situation where you might have a virtual bridge, or a bridge to an upstream network, and want a Docker service to be exposed to that network, without needing to map a port to the container service, Docker can automate this process.
Assume you have an external network that your host has a bridge configured for, 192.168.123.0/30 , and you want your container to be assigned an address from that pool, you can start by creating the network entry for Docker’s side:
docker network create -d bridge --subnet=192.168.123.0/30 --gateway=192.168.123.1 -o parent=br0 hostNetwork0
so when you create containers attached to that network, using --net hostNetwork0 , it will be assigned an address from this pool:
docker run -d --name nginx --net hostNetwork0 nginx
and you can see this assignment using docker inspect :
$ docker inspect nginx | grep IPAddress "IPAddress": "192.168.123.2",
and connect to the specificed port inside the container without needing port forwarding:
$ curl -Ik http://192.168.123.2 HTTP/1.1 200 OK Server: nginx/1.17.6 Date: Thu, 16 Jan 2020 08:15:07 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 19 Nov 2019 12:50:08 GMT Connection: keep-alive ETag: "5dd3e500-264" Accept-Ranges: bytes
This will allow you to, additionally, scope your container workloads into security groups that might already exist at your network level, without needing to configure the host for each workload being created — this is particularly useful if your entire platform might not be containerized, or if these are groups of services that might require an Ingress address, where some might not (similar to when you might not wish to expose a port).
More about Docker networks can be found here.