Pangolin: expose home services safely through a VPS
The most common question in self-hosting communities right now: how do I reach Immich, Jellyfin or Home Assistant from outside my house without opening ports or handing all my traffic to Cloudflare? One popular answer is Pangolin, a self-hosted tunneled reverse proxy with built-in login. You run it on a small VPS, your home server dials out to it, and nothing at home is exposed to the internet. Here's how it works and how to set it up.
What Pangolin is
Pangolin bundles four pieces so you don't wire them together yourself:
- Pangolin: the dashboard and API where you define sites and resources.
- Gerbil: a WireGuard manager that terminates the tunnels on the VPS.
- Traefik: the reverse proxy that serves your domains and gets the HTTPS certificates.
- Newt: a small agent that runs at home (a container is enough) and opens the outbound tunnel to the VPS.
Visitors hit the VPS, Pangolin checks who they are, and only then is traffic sent down the tunnel. Because the connection is outbound from home, it works behind CGNAT, double NAT or a router you can't configure. If your home connection has no public IPv4 address, this is the reason to use a VPS at all.
Pangolin vs. the alternatives
- Cloudflare Tunnel: easiest, but Cloudflare terminates TLS and sees all your traffic, and video streaming through it is against their terms for some plans.
- Plain reverse proxy + port forward: simple, but needs a public IP and exposes your home network. See Caddy vs. Nginx vs. Traefik.
- WireGuard, Tailscale or NetBird: best when only you need access. Compare them in WireGuard vs. Tailscale vs. NetBird. Pangolin is for when family or friends need a normal URL in a browser.
What you need
- A VPS with a public IPv4 address. 1 vCPU and 1 to 2 GB RAM is enough for Pangolin itself; check the VPS size calculator if you plan to add more. Use a netcup voucher to cut the first bill.
- A domain you control, with a wildcard DNS record (
*.example.com) and the dashboard host (pangolin.example.com) pointing at the VPS. - A server at home running Docker.
Prepare the VPS first with the fresh VPS checklist (updates, SSH keys, firewall, Docker). Then open these ports:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 51820/udp sudo ufw allow 21820/udp
80/443 are for web traffic and certificates, the UDP ports are the WireGuard tunnels. Check the current port list in the Pangolin docs before you copy this, as it can change between releases.
1. Install Pangolin on the VPS
Pangolin ships an interactive installer that writes the Docker Compose and Traefik config for you. Get the installer from the official docs at docs.pangolin.net (read the script before you run it), then run it as root in an empty directory:
mkdir -p ~/pangolin && cd ~/pangolin # download the installer as described in the docs, then: sudo ./installer
It asks for your base domain, the dashboard domain, an email address for Let's Encrypt and your admin login. Say yes to the Docker containers when asked, and keep the admin email and password in your password manager (Vaultwarden is a good home for them). When it finishes, open https://pangolin.example.com and log in.
2. Create a site and connect Newt
In the dashboard, add a site: that is one location, such as your home server. Choose the Newt connector and Pangolin shows a ready-made Compose snippet with an ID and secret. Put it on the home machine:
services:
newt:
image: fosrl/newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://pangolin.example.com
- NEWT_ID=your-id-from-the-dashboard
- NEWT_SECRET=your-secret-from-the-dashboard
docker compose up -d
The site should turn green in the dashboard within seconds. If it doesn't, check docker compose logs newt and make sure UDP 51820 isn't blocked on the VPS.
3. Publish a service
Add a resource: pick the site, enter a subdomain like photos.example.com, and set the target to the internal address of the app, for example http://192.168.1.20:2283 for Immich. Newt reaches it over the LAN, so the app itself never needs to be public. Pangolin gets the certificate on its own.
By default a resource is protected by Pangolin's login, so strangers see a sign-in page and not your app.
4. Add proper single sign-on
Pangolin supports external identity providers over OIDC. A very popular pairing in the self-hosting crowd is Pocket ID, a tiny passkey-only OIDC provider, which is much lighter than Authentik or Keycloak. Run it on the same VPS, add it under Identity Providers in Pangolin, and everyone logs in with a passkey instead of a password. You then decide per resource who may open it.
Two practical tips:
- Mobile apps can't show a login page. For Immich, Jellyfin or Home Assistant apps, use a resource-level bypass, a share link with header tokens, or keep those apps behind a VPN. Test the app on mobile data before you tell the family it works.
- Back up the Pangolin config. The
configfolder holds your database, certificates and secrets. Losing it means rebuilding every site and resource. Add it to your restic backup.
Security notes
- Keep the dashboard on its own subdomain and enable two-factor or passkeys for the admin account.
- Only publish what must be public. Admin panels (Portainer, Proxmox, router UIs) belong behind a WireGuard tunnel, not on a public URL.
- Update the containers regularly. A reverse proxy on the internet is the part of your setup that gets attacked first.
- Consider CrowdSec in front of Traefik to block repeat offenders. Many Pangolin users run it.
Is it worth it?
If you only need access for yourself, a VPN is simpler. If you need family or friends to open a normal link, you're behind CGNAT, or you don't want a third party seeing your traffic, Pangolin on a cheap VPS is one of the nicest setups around right now. The VPS costs a few euros a month, and because the tunnel is outbound-only, your home IP and network stay hidden.