Self Hosting

Conquering CGNAT and Bad Gateway Errors: A Self-Hosting Journey with Nginx, Cloudflare, and Podman

Embarking on the self-hosting adventure is exhilarating, but it can be a winding road filled with unexpected detours. Recently, I hit a roadblock while trying to expose my locally hosted services to the world. My excitement about using Podman, Nginx Proxy Manager, and a shiny new domain name quickly turned into frustration when I encountered the dreaded “Bad Gateway” error. Sound familiar? Let me share my journey and how I finally overcame this hurdle.

My setup was fairly standard for a budding self-hoster: an Arch Linux machine running Podman containers, orchestrated by Nginx Proxy Manager, and all accessible locally through Cockpit. Everything worked seamlessly within my home network. The challenge arose when I wanted external access. My ISP, like many, uses CGNAT, which prevents direct port forwarding. This is where Cloudflare Tunnel came to the rescue, offering a way to bypass this limitation.

I followed the Cloudflare documentation, setting up the tunnel and configuring a CNAME record pointing my domain to my server’s private IP address. Nginx Proxy Manager was listening on port 80, ready to direct traffic to my services, including a test ConvertX instance running on port 3000. I initially configured the Cloudflare Tunnel to use HTTPS on port 443, but the “Bad Gateway” error persisted. Switching to HTTP on port 80 didn’t help either.

After some head-scratching, I turned to ChatGPT for assistance. It suggested using network_mode: host in my Docker Compose file. While this temporarily resolved the external access issue, it broke access to the Nginx Proxy Manager admin page from within my local network. Clearly, this wasn’t a viable solution.

The Root of the Problem and the Solution

After more digging, I realized the issue stemmed from how I was configuring the upstream server in Nginx Proxy Manager. I was using my local IP address (e.g., 192.168.1.100) instead of the container’s IP address within the Podman network. Because the Cloudflare Tunnel was terminating on the host machine, Nginx Proxy Manager needed to forward requests to the containers within the Podman network, not the host’s loopback address.

Here’s how I finally fixed it:

  • Identify Container IP: Use podman inspect to find the container’s IP address within the Podman network.
  • Configure Nginx Proxy Manager: In the Nginx Proxy Manager admin panel, set the upstream server for your service to use the container’s IP address and the correct port.
  • Verify Cloudflare Tunnel: Ensure your tunnel is running and healthy, and your DNS records are correctly configured.

With these changes, everything clicked into place. I could finally access my services externally via my domain name, and the Nginx Proxy Manager admin panel remained accessible within my local network. This experience highlighted the importance of understanding the network interactions between Cloudflare Tunnel, the host machine, and containerized services within Podman.

This journey, though frustrating at times, taught me a valuable lesson about networking and containerization in a self-hosting environment. Hopefully, sharing my experience will help others avoid similar pitfalls and enjoy the fruits of their self-hosting labors.

Leave a Reply

Your email address will not be published. Required fields are marked *