Related Posts
If we launch a Docker container without expose any port from it toward Docker Host machine,in which we installed some application. Now how we access that application or Apache from outside world.
In this post, we would see how we could do port forwarding for running Docker container.So for this scenario we need to use IPTables, so whatever traffic comes to host on that port will redirect towards to Docker container.

Setup

For this post, we have setup like below.

Docker Host

#docker -v
Docker version 17.06.0-ce, build 02c1d87

#lsb_release -d
Description:	Ubuntu 16.04.3 LTS

IP Address : 192.168.43.47

Docker Container

#docker ps 
CONTAINER ID   IMAGE    COMMAND      CREATED             STATUS              PORTS   NAMES
e5b5c4cb0297   debian   "/bin/bash"  48 seconds ago      Up 47 seconds               Apache

#docker images debian
REPOSITORY TAG       IMAGE ID       CREATED       SIZE
debian     latest    978d85d02b87   5 months ago  123MB

Let's start Docker from Debian latest image.

Start Docker Container

For how to pull and start Docker read previous Post

#docker images debian
REPOSITORY   TAG      IMAGE ID       CREATED        SIZE
debian       latest   978d85d02b87   5 months ago   123MB

#docker run -it --hostname web-server --name Apache debian /bin/bash 
root@web-server:/# ip a l eth0
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever

#docker ps 
CONTAINER ID   IMAGE    COMMAND      CREATED             STATUS              PORTS   NAMES
e5b5c4cb0297   debian   "/bin/bash"  48 seconds ago      Up 47 seconds               Apache

So we have created one Docker container with Apache name and web-server Host name from Debian image having 172.17.0.3/16 IP Address.

Now let's start installing Apache on this machine.

root@web-server:/# apt-get update 
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]                                 
Ign http://deb.debian.org jessie InRelease                         

..........

Fetched 9988 kB in 37s (264 kB/s)
Reading package lists... Done

root@web-server:/# apt-get install apache2
Reading package lists... Done
Building dependency tree       
Reading state information... Done

With above yellow font commands used will install Apache, it will ask for "y" once for installation.

Start Apache on Docker container.

root@web-server:/# /etc/init.d/apache2 start

Setup IPTables

Now we need to deploy IPTables on Host machine so that we could connect Docker container Apache from outside world.

First we should check port 80 on Docker Host machine.

#nc -w 5 -v 192.168.43.47 80
nc: connect to 192.168.43.47 port 80 (tcp) failed: No route to host

Let's deploy IPTables for Docker Container IP Address: 172.17.0.3

#iptables -t nat -A POSTROUTING --source 172.17.0.3 --destination 172.17.0.3 -p tcp --dport 80 -j MASQUERADE

#iptables -t nat -A DOCKER ! -i docker0 --source 0.0.0.0/0 --destination 0.0.0.0/0 -p tcp --dport 80  -j DNAT --to 172.17.0.3:80

#iptables -A DOCKER ! -i docker0 -o docker0 --source 0.0.0.0/0 --destination 172.17.0.3 -p tcp --dport 80 -j ACCEPT

Check IPTables with below command.

#iptables -S DOCKER| grep 172.17.0.3
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT

#iptables -t nat -S DOCKER| grep 172.17.0.3
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.3:80

#iptables -t nat -S POSTROUTING| grep 172.17.0.3
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE

let's check port connectivity once again

#nc -w 5 -v 192.168.43.47 80
Connection to 192.168.43.47 80 port [tcp/http] succeeded!

we can check it on browser as well like below.

 

 

 

 

 

 

 

 

I have change my index.html file in Document Root.

root@web-server:/var/www/html# cat index.html
<h3>DOCKER DEBIAN SERVER</H3>
<font color=green><h3>Thanks to IPTables</font></h3>

Now check it again.

 

 

 

So. It works, Just three IPTables rule away. NO need to use -p option or rerun Docker from new image.

Small video on same
-------------------