<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pangolin on Backend Engineering Strategy Tools</title><link>https://backend-engineering-strategy-tools.github.io/site/tags/pangolin/</link><description>Recent content in Pangolin on Backend Engineering Strategy Tools</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 22 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://backend-engineering-strategy-tools.github.io/site/tags/pangolin/index.xml" rel="self" type="application/rss+xml"/><item><title>Tunneled reverse proxy platforms</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/tunneled-reverse-proxy/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/tunneled-reverse-proxy/</guid><description>&lt;p&gt;A step beyond raw tunnels. These platforms expose services running on a private network as public HTTPS URLs — no open ports, no public IP required. The key difference from a VPN: you don&amp;rsquo;t get network-level access to the remote machine, you get a link to a specific service.&lt;/p&gt;
&lt;p&gt;Typical flow:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Internet → public server (VPS) → tunnel → private network → your service
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The private machine maintains an outbound connection to the public server. Inbound traffic arrives at the public server and is forwarded back through the tunnel to the service.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pangolin"&gt;Pangolin
&lt;/h2&gt;&lt;p&gt;Self-hosted platform built specifically for this use case. You run the server component on a VPS; client agents (called Newt) run on machines inside your private network and establish outbound tunnels. Services get public HTTPS URLs. Access control is built in — you can gate services behind auth without touching the service itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Components&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pangolin&lt;/strong&gt; — the server, runs on a VPS, handles routing and auth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Newt&lt;/strong&gt; — the tunnel client, runs on private machines, connects out to Pangolin&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gerbil&lt;/strong&gt; — WireGuard-based tunnel layer (handled automatically)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traefik&lt;/strong&gt; — reverse proxy, managed by Pangolin for routing&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# On the VPS (docker-compose)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Pangolin + Traefik + Gerbil run together&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# On a private machine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run -e SERVER_URL&lt;span style="color:#f92672"&gt;=&lt;/span&gt;https://pangolin.yourdomain.com &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -e TUNNEL_SECRET&lt;span style="color:#f92672"&gt;=&lt;/span&gt;... &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fosrl/newt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Services then appear at subdomains: &lt;code&gt;service.yourdomain.com&lt;/code&gt; — proxied through the tunnel, with optional SSO/auth in front.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Property&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Self-hosted&lt;/td&gt;
 &lt;td&gt;Yes — you own the VPS and the data&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Open ports on private network&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Public IP required&lt;/td&gt;
 &lt;td&gt;VPS only (not home)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Auth built in&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Cost&lt;/td&gt;
 &lt;td&gt;Free, open source&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Maturity&lt;/td&gt;
 &lt;td&gt;Newer project (2024–)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Good fit for homelabs where you want public-facing services but don&amp;rsquo;t want to expose your home IP or open ports on your router.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="ngrok"&gt;ngrok
&lt;/h2&gt;&lt;p&gt;The original in this space. Run a single command, get a public URL. No server to manage — ngrok&amp;rsquo;s infrastructure handles it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ngrok http &lt;span style="color:#ae81ff"&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# → https://abc123.ngrok.io&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The URL changes on every restart unless you&amp;rsquo;re on a paid tier. Custom domains, persistent tunnels, and traffic inspection (useful for debugging webhooks) are paid features.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Property&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Self-hosted&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Open ports on private network&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Auth built in&lt;/td&gt;
 &lt;td&gt;Yes (paid)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Cost&lt;/td&gt;
 &lt;td&gt;Free tier limited; paid for custom domains&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Maturity&lt;/td&gt;
 &lt;td&gt;Established, widely used&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Best for: quick testing, webhook development, demos. Not ideal for a permanent homelab setup due to the dependency and cost at scale.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="frp-fast-reverse-proxy"&gt;frp (Fast Reverse Proxy)
&lt;/h2&gt;&lt;p&gt;Lightweight, self-hosted. You run &lt;code&gt;frps&lt;/code&gt; (server) on a VPS and &lt;code&gt;frpc&lt;/code&gt; (client) on private machines. More DIY than Pangolin — you configure the routing yourself, no built-in auth or dashboard.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# frps.toml (on VPS)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;bindPort&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# frpc.toml (on private machine)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;serverAddr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;your-vps-ip&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;serverPort&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[[proxies]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;my-service&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;type&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localPort&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;customDomains&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;[&amp;#34;service.yourdomain.com&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Property&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Self-hosted&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Open ports on private network&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Auth built in&lt;/td&gt;
 &lt;td&gt;Basic (token auth between client/server)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Cost&lt;/td&gt;
 &lt;td&gt;Free, open source&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Maturity&lt;/td&gt;
 &lt;td&gt;Established, widely used in homelab&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Good fit if you want full control and are comfortable wiring things together. No UI — config files only.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="expose-beyondcode"&gt;Expose (BeyondCode)
&lt;/h2&gt;&lt;p&gt;PHP-based self-hosted ngrok alternative. Dashboard included, custom domains, multiple tunnels.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;expose share http://localhost:8080
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Less common than frp or Pangolin, but polished for a self-hosted tool.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="comparison"&gt;Comparison
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;Pangolin&lt;/th&gt;
 &lt;th&gt;ngrok&lt;/th&gt;
 &lt;th&gt;frp&lt;/th&gt;
 &lt;th&gt;Expose&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Self-hosted&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Auth / access control&lt;/td&gt;
 &lt;td&gt;Yes (built-in)&lt;/td&gt;
 &lt;td&gt;Paid&lt;/td&gt;
 &lt;td&gt;No (DIY)&lt;/td&gt;
 &lt;td&gt;Basic&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Dashboard&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Custom domains&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Paid&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Complexity&lt;/td&gt;
 &lt;td&gt;Medium&lt;/td&gt;
 &lt;td&gt;Low&lt;/td&gt;
 &lt;td&gt;Medium&lt;/td&gt;
 &lt;td&gt;Medium&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Maturity&lt;/td&gt;
 &lt;td&gt;Newer&lt;/td&gt;
 &lt;td&gt;Established&lt;/td&gt;
 &lt;td&gt;Established&lt;/td&gt;
 &lt;td&gt;Moderate&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="when-to-use-which"&gt;When to use which
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Pangolin&lt;/strong&gt; if you want a self-hosted, permanent setup with auth and public URLs for homelab services. The right choice if you&amp;rsquo;re already running a VPS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ngrok&lt;/strong&gt; for quick tests, webhook development, or one-off sharing. Not for permanent services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;frp&lt;/strong&gt; if you want maximum control and minimal overhead, and are comfortable configuring a reverse proxy separately.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="related"&gt;Related
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;For network-level access (not service URLs) → &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/tunnels/" &gt;Tunnels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For SSH entry points → &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/bastion/" &gt;Bastion / jump server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>