Setup guide · ~5 minutes

How to reach any self-hosted app from anywhere

Self-hosting is the easy part. Getting to your server when you are not at home is where most people stall, because the usual answer is port forwarding plus dynamic DNS plus a reverse proxy plus certificates. This guide replaces that stack with one container, in about five minutes, and it works even if your ISP has you behind CGNAT.

What you need

  • An app that serves HTTP. If you can open it in a browser on your LAN, it works here.
  • One command's worth of access to a machine on that network. You never touch the router.
  • Enough upload bandwidth if you are streaming video. 10 Mbps carries one 1080p stream, 4K wants about 35. Setup measures this for you.

Step 1: Create an account and pick a plan

Sign up, verify your email, pick a tier. You pay per server, not per app or per device, so one plan covers everything on that machine:

  • Basic: 20 Mbps for $4/mo. Fits one 1080p stream.
  • Plus: 50 Mbps for $8/mo. Fits 4k stream or 2–3 concurrent 1080p.
  • Pro: 100 Mbps for $15/mo. Fits multi-user households, 4k remux.

Throughput is the cap on our end. If your home upload is 12 Mbps, the 100 Mbps plan buys you nothing. Start small; changing plans later is two clicks in the billing portal.

Step 2: Find your app's address and port

You need two things: the LAN IP of the machine running the app, and the port it listens on. Together they look like 192.168.1.50:8096. Common defaults:

AppDefault port
Jellyfin8096Media streaming
Plex32400Media streaming
Immich2283Photo library
Navidrome4533Music streaming
Audiobookshelf13378Audiobooks and podcasts
Home Assistant8123Home automation
Radarr7878Authentication off by default
Sonarr8989Authentication off by default

Confirm against your own setup rather than trusting the table. Any of these can be remapped in a compose file, and plenty of people have. If you are unsure, the port is whatever you type into your browser at home.

Step 3: Run the agent

After checkout you land on a setup page with your registration token already filled into ready-to-paste commands. The Docker one looks like this:

docker rm -f tunnelo 2>/dev/null; docker run -d --name tunnelo --restart unless-stopped --cap-add NET_ADMIN --device /dev/net/tun -v tunnelo-agent:/var/lib/tunnelo-agent -e TUNNELO_TOKEN=YOUR-TOKEN -e TUNNELO_SERVICE_URL=http://192.168.1.50:8096 ghcr.io/abiteman/tunnelo-agent:latest

Point TUNNELO_SERVICE_URL at the LAN IP from step 2. Never localhost or 127.0.0.1: inside the agent's own container those mean the container itself, not your server, and this is the single most common setup mistake. The leading docker rm -f tunnelo 2>/dev/null; makes the command safe to re-run after a typo. There is a curl | sh installer for bare metal and an Unraid template in Community Apps.

Running more than one app? Swap TUNNELO_SERVICE_URL for TUNNELO_SERVICES=192.168.1.50:8096,2283,8123. Bare ports after the first reuse that host. Each app gets its own https address on the same tunnel, and they share your plan's throughput rather than multiplying it.

Already running WireGuard on a router (OpenWrt or pfSense) or a NAS? Or did docker run fail because the host has no /dev/net/tun? Use external mode. The agent stays unprivileged and hands you a wg-quick config for whatever you already run.

Step 4: Turn on authentication first

This step is easy to skip and expensive to skip. The moment the tunnel is up, that address is reachable by anyone who knows it. Media servers like Jellyfin and Plex force a login out of the box, so they are fine. Plenty of self-hosted tools do not: Radarr and Sonarr ship with authentication disabled, and several dashboards and *arr-adjacent utilities assume they will only ever be on a trusted LAN.

Open each app's settings and enable authentication before you expose it, not after. The tunnel gives your app a public address; it does not give it a login screen.

Step 5: Connect and use your address

The setup page updates on its own, usually inside a minute. When it flips to Connected you get your permanent address (your-name.tunnelo.app) and an upload speed test result. Pay attention to that number: it is the honest ceiling on streaming, and knowing it up front beats debugging buffering complaints later.

Open the address in any browser, or enter it as the server URL in a native app. Everything passes through unchanged, including the parts that break on naive proxy setups: range requests for seeking, websockets for live updates, and large file transfers.

Troubleshooting & FAQ

Which apps work with this?

Anything that serves HTTP. The gateway maps a subdomain to an address and port on your tunnel and forwards traffic unchanged, so it never needs to know what is on the other end. Media servers are the common case and the proxy is tuned for them, but a dashboard, a wiki, a git server, or an internal tool all work the same way.

What does not work?

Anything that is not HTTP. Game servers, SSH, raw TCP or UDP services, and SMB shares are out of scope, because the gateway routes by hostname and there is no hostname in those protocols. If your app is reachable in a browser, it will work here.

Can I expose several apps at once?

Yes, and this is the normal setup. Set TUNNELO_SERVICES to a comma-separated list instead of a single TUNNELO_SERVICE_URL and each app gets its own https address on the same tunnel. There is no cap on how many. They share your plan throughput rather than multiplying it, because the ceiling is per server.

Do I need to open ports on my router?

No, and there is nothing useful you could open. Your server dials out to the gateway the same way a browser dials out to a website, so no inbound connection is ever required. That is what makes it work behind CGNAT, Starlink, 5G home internet, and ISP routers with no usable admin page.

How fast will it be?

Your home upload speed is almost always the real limit, not your plan. Figure roughly 10 Mbps of upload per 1080p video stream and about 35 for 4K. Anything that is not video barely registers. Setup runs a speed test so you see your actual number before you rely on it.

Is my traffic private?

It is encrypted the whole way: HTTPS from your device to the gateway, then WireGuard from the gateway to your server. We do not inspect what passes through and keep no record of what you opened or when.

What if I already run WireGuard?

Use external mode. The agent runs unprivileged and writes a wg-quick config you add to your existing setup, so your private key never leaves your machine. This is also the answer if docker run fails on /dev/net/tun, which happens on some restricted VMs and cloud hosts.

Do I pay per app or per device?

Neither. Pricing is per server. Every app behind that tunnel and every device that connects to it is included. Plans differ only in tunnel speed.

Guides for specific setups

Ready to try it?

One command and your server is reachable from anywhere, minus the router surgery. Every plan starts with a free trial.

Get your address