Expose LXC web containers to the Internet using a reverse proxy

I’m new to this field. :see_no_evil:

I’d like to get your opinion on my structure for exposing containers on the internet. My technique works pretty well. I use Caddy as a reverse proxy only, and therefore as a TLS terminator, which is very convenient.

The containers only listen on port 80 via Nginx, and I direct everything to Caddy. I have a functional iptables rule to open port 443 from the Caddy container to the host machine, so I can expose the Caddy container server on the internet.

# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to

Do you think there’s a better technique for exposing web servers from an LXC container? Should I use Nginx, HAProxy instead of Caddy (I admit I like Caddy’s automated TLS ease)?

Note: Using iptables, I feel like I get better performance than the built-in proxy of Incus.

Caddy is wonderful. It is a good choice. :+1:

Yes, it’s a fantastic product, one of my top software picks along with Tailcale over the past three years.

From a security standpoint, I think it would be wiser to run Caddy in a VM instead of a container, given that it’s exposed to the internet frontally (WAN) ?

Should any box connected directly to the internet have something like a Pfsense to avoid exposing containers directly?

1 Like

Have you tried Tailscale Funnel to expose the services in your containers or just your Caddy container to the Internet? At present, Tailscale Funnel can expose only services that run on the same Tailnet machine, so in order to expose all of the services that run in your network, you have two general network configuration options:

  • Run Tailscale Funnel on all of the machines in your Tailnet that run your services.
  • Run Tailscale Funnel only on your Caddy container to expose just the Caddy reverse proxy to the Internet and let Caddy forward requests to the other services in your network, including services that run on machines that aren’t in your Tailnet (i.e. that don’t run the Tailscale client).

Tailscale Funnel effectively replaces port forwarding on your router, dynamic DNS, and a reverse proxy like Caddy, Nginx, or HAProxy, though using a reverse proxy can simplify a Tailscale Funnel configuration where you run services in multiple containers.

I’ve just started using Tailscale Funnel, so I’m still exploring what it can do, but so far I have found it very use to use.