Port forwarding redirects traffic arriving on one port to a different port or internal address — commonly used to expose an internal application on a standard port, or route traffic between services.
Common Use Cases
- Forwarding external port 80/443 to an internal application running on a non-privileged port
- Redirecting traffic to a service running inside a Docker container or on a different internal machine
- Making an internal-only service temporarily accessible for testing
Method 1 — Nginx Reverse Proxy (Recommended for HTTP/HTTPS)
For web applications, a reverse proxy is generally preferable to raw port forwarding — see Nginx as a Reverse Proxy for Node.js/Docker Apps for the full guide. This approach also lets you add SSL termination and additional routing logic.
Method 2 — iptables Port Forwarding (Non-HTTP Traffic)
Forward external port 8080 to an internal service on port 3000:
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 3000
Make this persistent:
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
Method 3 — Forwarding to a Different Internal IP (NAT)
If forwarding to a different machine on a private network (e.g. between VPS instances):
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:3000
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Requires IP forwarding to be enabled:
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Method 4 — Docker Port Publishing
For containers, this is simply the -p flag, which handles the underlying port forwarding automatically:
docker run -p 8080:3000 myapp
Method 5 — SSH Local Port Forwarding (Temporary/Testing)
Useful for temporarily accessing an internal-only service from your local machine without exposing it publicly at all:
ssh -L 8080:localhost:3000 deploy@YOUR_SERVER_IP
This makes the remote service on port 3000 available at localhost:8080 on your local machine, tunneled securely through SSH.
Allow the Forwarded Port Through the Firewall
sudo ufw allow 8080/tcp
Verifying Port Forwarding Works
curl http://YOUR_SERVER_IP:8080
Common Errors
Forwarding rule doesn't work — verify IP forwarding is enabled (for DNAT scenarios) and that the firewall allows the external port.
Rules disappear after reboot — ensure iptables-persistent is installed and rules were saved with netfilter-persistent save.
"Address already in use" — another process is already using the target port on the destination; check with ss -tulpn on that machine.
Best Practices
- Prefer a proper reverse proxy (Nginx) over raw port forwarding for HTTP/HTTPS traffic
- Only forward ports that genuinely need external access
- Document any port forwarding rules, since they can be confusing to troubleshoot later without context
Related Articles
- Nginx as a Reverse Proxy for Node.js/Docker Apps
- Understanding iptables and nftables (Advanced Firewall Rules)
- How to Configure UFW Firewall on a Linux VPS
