Introduction

In earlier articles we’ve talked about docker images, creating and running docker containers as well as the docker hub. In this post, we’ll talk about Docker networking and specifically port redirection. An understanding of how port redirection works in the container is very useful while dockerising web applications that rely on apache or nginx. Before getting started let’s check what containers and images we have available on our system.

[sahil@linuxnix ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[sahil@linuxnix ~]$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[sahil@linuxnix ~]$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
sahilsuri008/linuxnix-docker v1 e1c1d07a11b5 22 hours ago 182MB
ubuntu 16.04 13c9f1285025 3 weeks ago 119MB
[sahil@linuxnix ~]$

From the above output, we can determine that we have two images and zero containers running or in a stopped state on this system. For the purpose of this demonstration, we don’t be using the Ubuntu image or the image that we created. Instead, we’ll pull an image for nginx and run it to exemplify how port redirection would work. So, let’s download the nginx image.

[sahil@linuxnix ~]$ docker run -d nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
fc7181108d40: Pull complete
d2e987ca2267: Pull complete
0b760b431b11: Pull complete
Digest: sha256:40d9770a77003d3114c332bcab42d4fb18a8cd28c4534162a2af6482641b876c
Status: Downloaded newer image for nginx:latest
09994d200778d9b781e7240bddf9b797f9007ee18e251a1cb5c770cd6f5c85a8
[sahil@linuxnix ~]$
[sahil@linuxnix ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
09994d200778 nginx "nginx -g 'daemon of…" 8 seconds ago Up 6 seconds 80/tcp silly_babbage
[sahil@linuxnix ~]$

The -d flag indicates that we want the container to run in detached mode i.e. we don’t want to connect to it once it launches. In case we did want to connect to it we would’ve used the -it flags which we used in earlier posts as well. If you take a look at the docker ls output you would notice that we have tcp port 80 exposed in the container. When going through documentation on Docker ports you are likely to come across two terms which are exposed and published. A port when exposed means that the port is open in the container and we could connect to the container on that port on the localhost. As published port implies that a host port is linked to the container port to provide access to the container from outside of the localhost. To know which port on an image will be exposed when a container is run from it we can use the docker image history command followed by the image name.

[sahil@linuxnix ~]$ docker image history nginx
IMAGE CREATED CREATED BY SIZE COMMENT
f68d6e55e065 8 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 8 days ago /bin/sh -c #(nop) STOPSIGNAL SIGTERM 0B
<missing> 8 days ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 8 days ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 0B
<missing> 8 days ago /bin/sh -c set -x && addgroup --system -… 54.1MB
<missing> 8 days ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~stretch 0B
<missing> 8 days ago /bin/sh -c #(nop) ENV NJS_VERSION=0.3.3 0B
<missing> 8 days ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.17.1 0B
<missing> 4 weeks ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 4 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:5ffb798d64089418e… 55.3MB
[sahil@linuxnix ~]$

Exposing the port 80 on the container means that we can connect to it via elinks or a similar utility on the localhost but we cannot connect to it via a web browser. To view the IP address assigned to the container we could run the docker inspect command followed by the container name.

[sahil@linuxnix ~]$ docker inspect silly_babbage | grep -i Ipadd
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
[sahil@linuxnix ~]$

From the above output, we can ascertain that the container IP address is “172.17.0.2”. To verify that nginx is running on port 80, let’s curl the IP address.

[sahil@linuxnix ~]$ curl http://172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[sahil@linuxnix ~]$

The above output validates that ngnix is running on port 80 inside the container. Now if you try to run the same command typing in localhost instead of the container IP address you will get an error. This is because the container port 80 is not linked to any port on the localhost to connect from. We’ll now launch another container and link the localhost port 80 to the container port 80 using the -p option with the docker run command.

[sahil@linuxnix ~]$ docker run -d -p 80:80 nginx
b4e38abf3ad6ea2ca563cd43b81c389641c909b1f7d54c46ea4c8383d76c96a8
[sahil@linuxnix ~]$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4e38abf3ad6 nginx "nginx -g 'daemon of…" 12 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp goofy_merkle
09994d200778 nginx "nginx -g 'daemon of…" 22 minutes ago Up 22 minutes 80/tcp silly_babbage
[sahil@linuxnix ~]$

Now in the output of the docker container ls command, we can see that our localhost port 80 is mapped to port 80 on the container. If we try to use the curl command now it should work.

[sahil@linuxnix ~]$ curl http://0.0.0.0
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

[sahil@linuxnix ~]$ curl http://localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[sahil@linuxnix ~]$

Conclusion

This concludes our introduction to port redirection in docker containers. We hope that you found this post to be useful and encourage you to experiment with port redirection in the containers you run.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.