Step-by-step guide to expose Docker web UIs, APIs, dashboards, and self-hosted services behind CGNAT using stable public forwarded ports.
# What public IPv4 does the internet see?
curl -4 ifconfig.me
# What is listening locally?
ss -tulpen
sudo ss -tulpen
# Test a local web/API service
curl -v http://127.0.0.1:8080
curl -v http://127.0.0.1:8000/health
# Check common Linux firewalls
sudo ufw status verbose
sudo iptables -S
sudo nft list rulesetYOUR_SETUP_TOKEN is shown after signup/trial checkout and binds the client to your assigned endpoint.
curl -fsSL https://api.needports.com/install | sudo bash -s YOUR_SETUP_TOKEN --accept-tos
sudo needports setup --dry-run
sudo needports expose custom --public-port 30000 --local-port 8080 --name "Service" --confirm --restart
curl -v http://your-needports-endpoint:30000CGNAT port forwarding, Vast.ai port forwarding, NeedPorts client commands, and NeedPorts security model.
This is the classic CGNAT symptom. The router receives a private or carrier-grade address while the internet sees the ISP shared public IP.
# Public IP seen by internet
curl -4 ifconfig.me
# On Linux, show the selected local source address for outbound traffic
ip route get 1.1.1.1
# On your router, compare WAN/Internet IP with curl output.
# If router WAN is 100.64.x.x, 10.x.x.x, 172.16-31.x.x, or 192.168.x.x,
# normal router forwarding cannot create a public inbound route.
DDNS can point a name at the public IP, but it cannot make the upstream NAT forward unsolicited inbound packets to you.
dig your-ddns-name.example
curl -4 ifconfig.me
nc -vz your-ddns-name.example 30000
If DNS is correct and the port still times out, the problem is routing/firewalling, not naming.
Many cellular plans use CGNAT. A service that is reachable on fiber may disappear when failover switches to LTE/5G.
# Run before and after failover
curl -4 ifconfig.me
nc -vz your-public-endpoint 30000
NeedPorts keeps the local machine making an outbound tunnel, so the public endpoint can remain stable across networks where normal inbound routing is impossible.
Use key-only SSH and map one assigned public port. Keep a fallback path.
Map only authenticated dashboards. Never expose the Docker daemon TCP socket.
Check whether the game requires TCP, UDP, or both. Test externally with the right protocol.
Use authentication, rate limits, and HTTPS/TLS for production APIs.
Start with a NeedPorts trial, map one service, and test the public port from another network before depending on it for production traffic.
Start a trialRead more guides