Introduction
In today's world of containerization, Docker has emerged as a popular solution for deploying and managing applications. A common use case involves forwarding network traffic from a specific port on the host computer to a port inside a Docker container. This can be especially useful when you want to expose a service running inside your container to the outside world, or when you need to set up a reverse proxy for load balancing.
In this article we'll walk you through the steps needed to forward a port to a Docker container using iptables, a powerful and flexible firewall utility available in most Linux distributions.
Identify the IP address of the Docker container
Run the following command to find the IP address of your Docker container:
docker inspect -f '{{.NetworkSettings.IPAddress }}' <CONTAINER_NAME_OR_ID>
Replace with your container name or ID. Note the IP address displayed in the output.
Port forwarding to Docker containers
Using Iptables
To forward a port to a Docker container using iptables, you can follow these steps:
Add iptables rules for forwarding: Now set iptables rules to forward the desired port to your Docker container. Replace <HOST_PORT> with the port number on the host computer, <CONTAINER_IP> with the IP address of your container, and <CONTAINER_PORT> with the port number inside the container.
sudo iptables -t nat -A PREROUTING -p tcp --dport <HOST_PORT> -j DNAT --to-destination <CONTAINER_IP>:<CONTAINER_PORT>
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
For example, if you want to redirect port 8080 from the host computer to port 80 on a Docker container with an IP 172.21.0.7, run the given commands:
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.21.0.7:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Save iptables rules: To make iptables rules persist across reboots, you can save them using the iptables-save command:
sudo iptables-save > /etc/iptables/rules.v4
Please note that the path to the rules file may vary depending on your Linux distribution.
Make the iptables rule persistent: If you are using a Debian/Ubuntu-based distribution, you can install the iptables-persistent package to make the rules persistent across reboots:
sudo apt-get install iptables-persistent
During installation, you will be asked if you want to save the current iptables rules. Select "Yes" to save the rules.
To forward a port to a Docker container using firewall-cmd, which is part of the firewalld utility on RHEL/CentOS/Fedora-based systems, follow these steps:
Add firewall-cmd rules for forwarding: Now configure firewall-cmd rules to forward the desired port to your Docker container. Replace <HOST_PORT> with the port number on the host computer, <CONTAINER_IP> with the IP address of your container, and <CONTAINER_PORT> with the port number inside the container.
First, enable masking on the active zone:
sudo firewall-cmd --zone=public --add-masquerade --permanent
Next, create the port forwarding rule:
sudo firewall-cmd --zone=public --add-forward-port=port=<HOST_PORT>:proto=tcp:toaddr=<CONTAINER_IP>:toport=<CONTAINER_PORT> --permanent
For example, to forward port 8080 on the host computer to port 80 on a Docker container with an IP address of 172.17.0.7, you would use the following command:
sudo firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toaddr=172.17.0.7:toport=80 --permanent
Reload firewall rules: After adding rules, you need to reload the firewalld configuration for the changes to take effect:
sudo firewall-cmd --reload
Now, port forwarding should work and all traffic arriving at <HOST_PORT> on the host computer will be forwarded to <CONTAINER_PORT> on the Docker container.
Using UFW
To forward a port to a Docker container using ufw (Uncomplicated Firewall), which is the default firewall tool on Ubuntu and other Debian-based systems, you need to follow these steps:
Enable UFW forwarding: Edit the UFW configuration file in /etc/default/ufw:
sudo nano /etc/default/ufw
Find the line containing DEFAULT_FORWARD_POLICY="DROP" and change it to DEFAULT_FORWARD_POLICY="ACCEPT":
DEFAULT_FORWARD_POLICY="ACCEPT"
Save the file and exit the editor.
Configure IP forwarding: Edit the sysctl configuration file in /etc/sysctl.conf:
sudo nano /etc/sysctl.conf
Add or remove the comment from the following line:
net.ipv4.ip_forward=1
Save the file and exit the editor. Apply the changes by running:
sudo sysctl -p
Update UFW rules: First create a new UFW rules file for port forwarding. Replace <HOST_PORT> with the port number on the host computer, <CONTAINER_IP> with the IP address of your container, and <CONTAINER_PORT>> with the port number inside the container.
sudo nano /etc/ufw/before.rules
Add the following lines to the top of the file, after the header comments:
*nat:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport <HOST_PORT> -j DNAT --to-destination <CONTAINER_IP>:<CONTAINER_PORT>
COMMIT
For example, to forward port 8080 on the host computer to port 80 on a Docker container with an IP address of 172.17.0.7, you would add:
*nat:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.7:80
COMMIT
Save the file and exit the editor.
Reload UFW: Finally, reload the UFW configuration for the changes to take effect:
sudo ufw disable
sudo ufw enable
Now, port forwarding should work and all traffic arriving at <HOST_PORT> on the host computer will be forwarded to <CONTAINER_PORT> on the Docker container.
Conclusion
In conclusion, forwarding a port to a Docker container using iptables is a simple process that involves identifying the container's IP address, adding the necessary iptables rules, and ensuring that the rules persist across reboots. By following the steps in this article, you can ensure that traffic sent to a specific port on the host computer is seamlessly redirected to the corresponding port within the container. This approach allows you to expose services running inside containers, set up reverse proxies, or implement load balancing, among other use cases, thus improving the flexibility and efficiency of your containerized infrastructure.