VPN Inside a Container
Section titled “VPN Inside a Container”You can run a real VPN inside your container and keep every published URL working. Which of the two ways you start it decides whether that holds: run the WireGuard configuration file your provider gives you and the URLs keep answering, or run the provider’s desktop app and they go dark. Both use the same provider, the same relay, and the same encryption; only the outcome for your published URLs differs. Read the next section before you start either one.
Why a full tunnel breaks inbound URLs
Section titled “Why a full tunnel breaks inbound URLs”Your container’s URLs (*-terminal-1.*, *-console-1.*, every service you publish) are reached through the Hoody Reverse Proxy, which preserves the visitor’s real IP all the way into the container. That is deliberate: your app sees who is calling, and hooks, permissions, and audit records all depend on that address being the visitor’s.
Your container’s reply is therefore addressed to a public IP. A full-tunnel VPN (AllowedIPs = 0.0.0.0/0) sends everything public into the tunnel, that reply included. The answer leaves through your VPN provider and never reaches the visitor who asked.
The symptom is not an error page. The connection is accepted, TLS completes, and then it hangs for roughly two minutes before failing. A packet capture shows the container answering correctly and the answer leaving on the VPN interface instead of the normal one. The container is not broken; its reply leaves on the wrong interface.
Hoody keeps replies to inbound proxy traffic on the path they arrived on, so a full tunnel and your published URLs can coexist. What no routing rule can fix is a firewall that drops the request before any routing decision exists, which is exactly what a VPN app’s kill switch is.
Use the config file, not the app
Section titled “Use the config file, not the app”Download the WireGuard configuration from your provider and run it with wg-quick.
# WireGuard userspace toolsapt-get update && apt-get install -y wireguard-tools
# Put the config your provider gave you in place.# wg-quick names the interface after the filename.install -m 600 wg0.conf /etc/wireguard/
# Upwg-quick up wg0
# Downwg-quick down wg0With the tunnel up, published URLs keep answering, and they keep answering when the tunnel is taken down and brought back up. Outbound traffic leaves through the VPN provider, so the server’s own IP is not exposed.
A VPN app with a kill switch, lockdown mode, or “block connections without VPN” applies a default-deny inbound firewall while connected. That drops the incoming connection before any routing decision happens, so no routing fix can help. There is nothing left to route.
- Kill switch armed: the published URL gets no answer (
curlreports HTTP000). - Kill switch removed: the URL answers again immediately.
- “Allow local network sharing” enabled: still no answer. The edge arrives carrying the visitor’s public IP. It is not local-network traffic, so a local-network exemption never matches it.
Turning the kill switch off to get your URLs back leaves you running a VPN app with its safety feature disabled. Run the config file instead.
Verify both directions
Section titled “Verify both directions”Check the tunnel and the URLs separately. They can fail independently, and knowing which one broke tells you where to look.
# Egress: does traffic leave through the VPN?# Compare this address with the one your provider assigned.curl https://ifconfig.me# Ingress: does the published URL still answer?curl -o /dev/null -s -w '%{http_code}\n' \ https://{project}-{container}-terminal-1.{server}.containers.hoody.com/# 200000 means the request never got an answer, which points to a kill switch armed inside the container. Go in over SSH and take the VPN down.
What stops working while a full tunnel is up
Section titled “What stops working while a full tunnel is up”These destinations are container-outbound, so keeping your inbound replies on course does nothing for them. While any full tunnel is up:
| Destination | Address | Status with a full tunnel |
|---|---|---|
| AI proxy | 198.51.100.1 | Unreachable |
| APT / package proxy | 198.51.100.2 | Unreachable |
That list is narrower than it looks. General internet access works, and ordinary name resolution works, because it goes through the tunnel like everything else. What you lose is the platform’s own internal shortcuts, not your connectivity.
Recover access when URLs go dark
Section titled “Recover access when URLs go dark”If your URLs have already gone dark, there are two ways back in.
Go in over SSH and stop the VPN:
ssh -i ~/.ssh/hoody-container-1 root@ssh.$serverName.containers.hoody.com
# then, inside the containerwg-quick down wg0# or quit the VPN appOr restart the container. VPN interfaces and their routing do not survive a restart. A restart returns the container to a clean network and your URLs come back with it.
How it works
Section titled “How it works”There is nothing for you to configure. When your container starts, Hoody installs a reply-path rule inside the container. Traffic your container initiates goes wherever your VPN sends it; traffic that answers the Hoody edge goes back to the edge.
Two consequences follow:
- The rule is installed at container start, before anything of yours runs. It has to be in place before a VPN starts, which is why it is done there and not later.
- A tunnel that is already running when the rule is installed takes precedence over it. That is another reason a restart fixes things: the restart puts the rule back in front.
How this differs from network configuration
Section titled “How this differs from network configuration”These are two different layers, documented on two different pages:
| Network Configuration | VPN inside the container (this page) | |
|---|---|---|
| Where it runs | On the host, outside your container | Inside your container, by you |
| What it speaks | SOCKS5, HTTP, HTTPS proxies | Whatever VPN client you install |
| Setup inside the container | None | Yours to install and run |
| Can the container bypass it | No | It is the container’s own tunnel |
Use Network Configuration when you want an exit IP change with no in-container setup and no way for the workload to escape it. Run a VPN inside the container when you need the provider’s actual tunnel: a specific relay, a WireGuard device, or a client only that provider ships.
Useful Questions
Section titled “Useful Questions”Can a VPN inside my container cut off my SSH access?
Section titled “Can a VPN inside my container cut off my SSH access?”No. SSH to a Hoody container does not travel over the container’s network at all. The host brokers it through the container runtime, so no route and no in-container firewall can reach it, with the tunnel up or a kill switch armed.
Will my published URLs survive a full tunnel?
Section titled “Will my published URLs survive a full tunnel?”Yes, with a WireGuard config file run by wg-quick. The URLs keep answering with the tunnel up and across tunnel restarts.
Why does my provider’s app break them?
Section titled “Why does my provider’s app break them?”Because its kill switch is a default-deny inbound firewall. It drops the connection before there is any routing decision left to fix. The URLs answer again the moment it is removed.
Does “Allow local network sharing” fix the app?
Section titled “Does “Allow local network sharing” fix the app?”No. The Hoody edge arrives with the visitor’s real public IP, so a local-network exemption never matches it.
Does the tunnel survive a container restart?
Section titled “Does the tunnel survive a container restart?”No. VPN interfaces and their routing are gone after a restart. That rules out a tunnel that persists across restarts, and it is also what gets you out of trouble when one has locked you out.
Which VPN providers work?
Section titled “Which VPN providers work?”Any provider that publishes a downloadable WireGuard configuration.
Do the AI proxy and APT proxy work?
Section titled “Do the AI proxy and APT proxy work?”No, not while a full tunnel is up: those are container-outbound and go into the tunnel. Ordinary DNS and general internet access are unaffected.
What’s Next
Section titled “What’s Next”Complete your networking setup:
- SSH Access → - Set this up first. A VPN cannot block it.
- Network Configuration → - Host-level exit IP routing, no in-container setup
- Firewall → - Host-enforced packet rules your container cannot touch
Key points:
- The Hoody edge preserves the visitor’s real IP, which is why a full tunnel would otherwise swallow your replies
- Replies to inbound proxy traffic stay on the path they arrived on
- A WireGuard config file keeps your URLs working; a VPN app’s kill switch takes them down
- SSH keeps working whatever the tunnel does
- A container restart clears any VPN state