Self-Hosting Pangolin: The Tunneled Reverse Proxy with Built-in Auth
Most self-hosters hit the same wall: you want to expose services to the internet, but you don't want to open ports on your router, manage certificates manually, or bolt on a separate authentication layer. You end up stitching together a reverse proxy, a tunnel, and an auth provider -- three separate systems that need to work in concert.
Pangolin combines all three into one self-hosted platform. It's a tunneled reverse proxy with built-in identity-aware access control. You install Pangolin on a VPS, run a lightweight WireGuard client (called Newt) on your home server, and get secure, authenticated access to your services without opening a single port on your home network.
What Makes Pangolin Different
The self-hosting networking landscape is crowded with reverse proxies (Traefik, Nginx, Caddy), tunneling solutions (Cloudflare Tunnels, Tailscale Funnel), and auth layers (Authelia, Authentik). Pangolin's value proposition is combining these into a single, cohesive system:
- Tunneled connections -- Your home server connects outbound to Pangolin via WireGuard. No port forwarding needed.
- Built-in authentication -- Users authenticate through Pangolin before reaching your services. Supports email/password, SSO, and one-time access links.
- Access policies -- Define who can access which services based on identity, email domain, or access tokens.
- Automatic HTTPS -- Let's Encrypt certificates managed automatically.
- Web dashboard -- Configure everything through a clean UI. No YAML files to manage after initial setup.
Think of it as a self-hosted alternative to Cloudflare Tunnels + Cloudflare Access, but running entirely on your own infrastructure.
Architecture Overview
Pangolin has two components:
- Pangolin Server -- Runs on a VPS with a public IP. Handles reverse proxying, TLS termination, authentication, and the management dashboard.
- Newt -- A lightweight WireGuard-based client that runs on your home server. Establishes an outbound tunnel to Pangolin Server and routes traffic to your local services.
The traffic flow:
User → Pangolin Server (VPS) → WireGuard Tunnel → Newt (Home Server) → Your Service
↑
Auth check happens here
Your home server never accepts inbound connections. Newt initiates the WireGuard tunnel outbound, and Pangolin routes authenticated requests through it.
Prerequisites
You need:
- A VPS with a public IP address (any cheap VPS works -- 1 CPU, 1 GB RAM is sufficient)
- A domain name pointed at your VPS IP
- Docker and Docker Compose on both the VPS and your home server
Setting Up Pangolin Server
On your VPS, create the Pangolin configuration and Docker Compose file:
# docker-compose.yml (on VPS)
services:
pangolin:
image: fosrl/pangolin:latest
container_name: pangolin
ports:
- "80:80"
- "443:443"
- "51820:51820/udp" # WireGuard
volumes:
- ./config:/app/config
- pangolin_data:/app/data
environment:
- PANGOLIN_DOMAIN=pangolin.yourdomain.com
- [email protected] # For Let's Encrypt
- [email protected]
restart: unless-stopped
volumes:
pangolin_data:
docker compose up -d
On first start, Pangolin will:
- Generate a WireGuard keypair
- Obtain a Let's Encrypt certificate for your domain
- Create the admin account
- Start the management dashboard
Access the dashboard at https://pangolin.yourdomain.com and log in with the admin email. You'll be prompted to set a password on first access.
Setting Up Newt (Home Server Client)
From the Pangolin dashboard, create a new "Site" (which represents your home server). This generates a Newt enrollment token.
On your home server:
# docker-compose.yml (on home server)
services:
newt:
image: fosrl/newt:latest
container_name: newt
environment:
- PANGOLIN_ENDPOINT=https://pangolin.yourdomain.com
- NEWT_TOKEN=your_enrollment_token_here
cap_add:
- NET_ADMIN
sysctls:
- net.ipv4.ip_forward=1
restart: unless-stopped
network_mode: host
docker compose up -d
Newt will connect to Pangolin Server, establish a WireGuard tunnel, and register itself. You should see the site appear as "Connected" in the Pangolin dashboard within seconds.
Adding Services
Once Newt is connected, adding services is done through the Pangolin dashboard:
- Navigate to your site
- Click "Add Resource"
- Configure the resource:
- Domain:
grafana.yourdomain.com - Target:
http://localhost:3000(the local address of the service on your home server) - Access Policy: Choose who can access it
- Domain:
Pangolin automatically obtains a TLS certificate for the subdomain and starts routing authenticated traffic through the WireGuard tunnel to your service.
No Caddyfile to edit. No Nginx configuration to reload. No DNS challenge to configure.
Access Control Policies
This is where Pangolin stands apart from a plain reverse proxy. Every resource can have an access policy:
Public Access
Anyone on the internet can reach the service (useful for blogs, public APIs):
Policy: Public
Authentication: None
Authenticated Users Only
Users must log in through Pangolin's auth page:
Policy: Authenticated
Authentication: Email/Password or SSO
Allowed users: all registered users
Restricted to Specific Users or Domains
Only certain email addresses or email domains can access the service:
Policy: Restricted
Allowed emails: [email protected], [email protected]
Allowed domains: @yourcompany.com
One-Time Access Links
Generate shareable links that grant temporary access -- useful for sharing a service with someone who doesn't have an account:
Policy: Link-based
Expiration: 24 hours
Max uses: 1
Pangolin vs the Alternatives
| Feature | Pangolin | Cloudflare Tunnels | Traefik + Authelia | Nginx Proxy Manager |
|---|---|---|---|---|
| License | Open source | Proprietary (free tier) | Open source | Open source |
| Self-hosted | Fully | Tunnel agent only | Fully | Fully |
| Tunneling | Built-in (WireGuard) | Built-in (cloudflared) | Requires separate setup | None (port forward) |
| Authentication | Built-in | Cloudflare Access ($) | Authelia (separate) | None built-in |
| Access policies | Built-in UI | Cloudflare dashboard | Authelia config files | None |
| HTTPS | Automatic | Automatic | Automatic | Automatic |
| Dashboard | Yes | Cloudflare dashboard | Traefik dashboard | Yes |
| Configuration | Web UI | Dashboard + CLI | YAML/labels | Web UI |
| Requires public IP | VPS only | No (Cloudflare edge) | Yes (on proxy host) | Yes |
| Data sovereignty | Complete | Cloudflare sees traffic | Complete | Complete |
| Setup complexity | Medium | Low | High | Low-Medium |
When to Choose Pangolin
- You want tunneling and authentication in a single, self-hosted system
- You have a cheap VPS and want full control over your infrastructure
- You don't want Cloudflare inspecting your traffic
- You need identity-aware access policies without running a separate auth provider
- You prefer a web UI over YAML configuration
When to Choose Cloudflare Tunnels
- You don't want to manage a VPS at all
- You want Cloudflare's DDoS protection and CDN
- You're fine with Cloudflare having visibility into your traffic
- You want the easiest possible setup with zero infrastructure management
When to Choose Traefik + Authelia
- You already run Traefik and want to add authentication
- You need deep Docker integration with label-based configuration
- You want maximum flexibility and don't mind managing multiple services
- You're in a Kubernetes environment
When to Choose Nginx Proxy Manager
- You just need a simple reverse proxy with a UI
- You don't need tunneling (you're already port forwarding)
- You don't need built-in authentication
- You want the lowest learning curve
Resource Requirements
Pangolin is lightweight:
Pangolin Server (VPS):
- 1 vCPU, 512 MB RAM minimum (1 GB recommended)
- 10 GB storage
- Any $4-6/month VPS will work (Hetzner, DigitalOcean, Vultr)
Newt (Home Server):
- Minimal footprint -- WireGuard is extremely efficient
- Less than 50 MB RAM
- Negligible CPU usage
WireGuard adds very little overhead to traffic. Expect near-native throughput for most home internet connections.
Practical Tips
Use a Dedicated Domain
Point a wildcard DNS record at your VPS:
*.home.yourdomain.com → VPS_IP_ADDRESS
Then each service gets its own subdomain: grafana.home.yourdomain.com, jellyfin.home.yourdomain.com, etc.
Multiple Sites
Pangolin supports multiple Newt clients. If you have services at different locations (home, office, a friend's server), each location runs its own Newt instance and connects to the same Pangolin server.
Backup Configuration
The Pangolin data volume contains your configuration, user accounts, and access policies. Back it up:
docker compose stop
tar czf pangolin_backup_$(date +%Y%m%d).tar.gz ./config
docker compose start
Monitor Tunnel Health
The dashboard shows connection status for each Newt client. Set up a simple health check to alert you if the tunnel drops:
# Check if Pangolin dashboard is reachable
curl -sf https://pangolin.yourdomain.com/health > /dev/null || echo "Pangolin down"
Verdict
Pangolin fills a genuine gap in the self-hosting ecosystem. Before it existed, getting tunneled, authenticated access to your services required wiring together at least two or three separate tools. Pangolin rolls tunneling (WireGuard), reverse proxying, TLS, and identity-aware access control into one system with a clean web interface. The trade-off is that you need a VPS, but a $5/month server is a small price for not opening ports on your home network and not routing traffic through Cloudflare. If you've been cobbling together Cloudflare Tunnels for the connectivity and Authelia for the auth, Pangolin is worth a serious look.