What Pangolin Actually Does
Running services at home or on a private server usually means picking between two uncomfortable options: open ports on your router and hope nothing gets probed, or pay for a managed tunneling service and hand your traffic to someone else. Pangolin cuts through that tradeoff by acting as a self-hosted tunnel server and authentication gateway in one stack – you own the exit point, you control the auth layer, and nothing has to punch through your firewall to get there.
The architecture is worth understanding before you touch a config file. Pangolin sits on a public-facing VPS and receives encrypted tunnel connections from your local machines using Newt, its purpose-built tunnel client. When a request hits your domain, Pangolin authenticates it, checks access rules, and forwards it through the tunnel to wherever that service actually lives. Your home server never needs a public IP. Your firewall stays closed.

What You Need Before Starting
You need a VPS with a public IP address – any major provider works, and even a small instance handles the load fine since Pangolin is not doing heavy computation. A domain name you control is also required, because Pangolin manages subdomains per resource and uses them to route requests correctly. Wildcard DNS pointing to your VPS IP is the cleanest approach: set an A record for your root domain and a wildcard CNAME or A record so that every subdomain resolves to the same machine without additional DNS edits each time you add a service.
On the VPS, you need Docker and Docker Compose installed. Pangolin ships as a compose stack, which keeps the setup portable and avoids dependency conflicts with anything else running on the box. Port 80 and 443 must be open for HTTP and HTTPS traffic, and Pangolin also uses a UDP port (default 51820) for the WireGuard-based tunnel connections from Newt clients. Check that your VPS firewall rules – both the cloud provider’s security group and any local ufw or iptables rules – allow those three ports before you start the stack.
Standing Up the Server Stack
Pangolin’s compose file bundles three services: Pangolin itself, Traefik as the reverse proxy and TLS terminator, and Gerbil, which manages the WireGuard interface that Newt clients connect to. Pull the official compose file from the Pangolin GitHub repository and create a config/ directory alongside it. Inside that directory you will place config.yml, which controls domain settings, database paths, and the admin credentials used to log in to the management dashboard.
The minimum viable config.yml sets your base domain, points Traefik to your email address for Let’s Encrypt certificate issuance, and defines the admin user. Once that file is in place, run docker compose up -d and Traefik will negotiate certificates for your domain automatically. Give it thirty to sixty seconds, then navigate to dashboard.yourdomain.com – Pangolin serves its management UI there by default. If you hit a certificate warning, the ACME challenge is still running; wait a moment and hard reload.
Inside the dashboard, the first thing to do is create an Organization. Pangolin structures everything – users, sites, resources – under organizations, which matters more if you are running this for multiple people or projects, but even for a solo setup it is required before anything else can be configured. Under your organization, create a Site. A site represents a physical or logical network where your services live – your home lab, a remote office, a second VPS. Each site gets a unique key that the Newt client uses to authenticate the tunnel.

After creating the site, Pangolin displays a Newt installation command pre-populated with your server address and site key. Copy that command. On the machine where your local services run – your home server, your NAS, wherever – install Newt using that command. Newt starts a WireGuard tunnel to Gerbil on the VPS, and within a few seconds the dashboard shows the site as connected. The tunnel runs over UDP and stays up through NAT, so it works behind double-NAT and CGNAT configurations that would block traditional port forwarding.
Adding Resources and Locking Them Down
A resource in Pangolin is a single service you want to expose – a Jellyfin instance, a Gitea repo, a Home Assistant dashboard, anything running on an HTTP or HTTPS port locally. In the dashboard, navigate to your site and add a resource. You assign it a subdomain (Pangolin fills in the base domain automatically), set the target as http://localhost:PORT or the LAN IP and port where the service actually runs, and choose an authentication method.
The authentication options are where Pangolin earns its position as a gateway rather than just a proxy. The simplest option is Pangolin’s built-in auth, which puts a login form in front of the resource using the user accounts you have created inside the dashboard. This is useful for internal tools that have no auth of their own. For services that already handle login themselves, you can bypass Pangolin auth entirely and just use the tunnel for network access. There is also an SSO integration path – if you are already running something like Authentik as a self-hosted SSO server, you can point Pangolin’s auth to it via OIDC, which lets you manage all access from a single identity provider rather than creating separate accounts in each tool.
Access control policies let you restrict resources further. You can whitelist specific email addresses or entire domains if you have SSO set up, which is particularly useful for sharing a service with one person without creating open access. IP allowlisting is available too, though it is less useful for the typical use case where you want access from anywhere. The policies apply per resource, so a public-facing portfolio site can have no auth while an admin panel on the same domain requires SSO with MFA enforced at the identity provider level.

One detail that trips up first-time setups: if your local service only listens on 127.0.0.1 rather than 0.0.0.0, Newt still reaches it fine because the tunnel terminates on the same machine. But if Newt is running on a different machine than the service – say, a router running Newt forwarding traffic to a NAS on the LAN – you need to use the actual LAN IP in the resource target, not localhost. Pangolin does not validate the target address at save time, so a wrong IP will save without error and silently fail to connect. Check the resource’s status indicator in the dashboard; a red dot means the tunnel is up but Pangolin cannot reach the target, which almost always points to a target address or port mismatch rather than a tunnel problem.





