Opening a port, but not listening on it
The following command creates a
container. The
-p
parameter forwards
port 8001 to the container:
$ docker run --rm -it --name no-listener -p 8001:8001 busybox /bin/sh
Because there is no
process in the container that listens on port 8001, trying to connect to this port from the host with
curl
results in the error message
Recv failure: Connection reset by peer:
$ curl localhost:8001
curl: (56) Recv failure: Connection reset by peer
Opening a port and listening it
The next command creates a container with a
webserver listening on port 8001:
$ docker run --rm -it --name listener -p 8001:8001 python:alpine python -m http.server --directory /etc 8001
Because -p 8001:8001
forwards the host's port 8001 to the container's port 8001, we can make a request to the webserver from the host:
$ curl localhost:8001/hostname
7d7872083d8c
Forwarding a port to a different port number
The following command uses -p
to forward port 7777 on the host to 8001 in the container:
$ docker run --rm -it --name listener -p 7777:8001 python:alpine python -m http.server --directory /etc 8001
With this forwarding, the webserver can be accessed from the host on port 7777:
$ curl localhost:7777/hostname
6d05678cc3b0
Accessing the host from the container
On the host, we determine the host's IP address used for Docker:
$ ip -br a | grep docker0
docker0 UP 172.17.0.1/16 fe80::42:36ff:fed5:1b8f/64
Then, still on the host, we start a web server:
$ python3 -m http.server --directory /etc 8001
Now, we create a container that accesses the web server running on the host:
$ docker run --rm -it --name client busybox wget -O- -q 172.17.0.1:8001/hostname
Creating a network
We create a dedicated network for the client and server containers:
$ docker network create -d bridge client-server-network
The server is started with the --network
command line option:
$ docker run --rm -it --name http-server --network client-server-network --hostname srv python:alpine python -m http.server --directory /etc 8001
The client is also started with the --network
command line option. Note how the client can specify the server by its hostname (srv
) which was specified with --hostname
when the server was started:
$ docker run --rm -it --name http-client --network client-server-network busybox wget -O- -q srv:8001/hostname
Connect from the host to a container in the network
First, we need to determine the IP number of the container running the web server:
$ docker inspect client-server-network | jq -r '.[] | .Containers | to_entries | .[] | .value | select(.Name == "http-server") | .IPv4Address'
172.18.0.2/16
We're now ready to establish a TCP/IP connection to the container from the host:
$ wget -O- -q 172.18.0.2:8001/hostname
srv
Exposing a container's port to the host
Again, we use the -p
option of docker run
to specify that a port on localhost
is forwared to a container:
$ docker run --rm -it --name http-server-2 --network client-server-network --hostname srv-2 -p 8888:8002 python:alpine python -m http.server --directory /etc 8002
We can now access the container on port 8888 (which is forawrded to port 8002):
$ wget -O- -q localhost:8888/hostname
srv-2