This guide walks you through self-hosting Pangolin, a modern reverse proxy and tunnel manager, and then connecting remote sites to it using Newt, its lightweight agent. By the end, you’ll have a secure way to expose internal services (like a home NAS or a development server) through your own domain, without opening ports on your router.
What You’ll Need
- A Linux server (Ubuntu 22.04/24.04 recommended) with a public IP address and root or sudo access.
- A domain name (or subdomain) that you can point to your server via DNS A records.
- Docker and Docker Compose installed on the server.
- Basic comfort with the command line and editing config files.
- For remote sites: a device (Raspberry Pi, old PC, or cloud VM) that runs Docker and can reach the internet.
Step-by-Step
- Set up DNS records. Create an A record for
pangolin.example.compointing to your server’s public IP. If you plan to use a wildcard for services, also add*.example.comas an A record (or CNAME) to the same IP. Wait for propagation (can take minutes to hours). - Install Docker and Docker Compose. On your server, run the official Docker install script:
curl -fsSL https://get.docker.com | sh. Then verify withdocker --versionanddocker compose version. - Create a project directory. Run
mkdir -p ~/pangolin && cd ~/pangolinto keep everything in one place. - Download the docker-compose.yml. Pangolin provides a sample compose file. Fetch it with
curl -L https://raw.githubusercontent.com/fosrl/pangolin/main/docker-compose.yml -o docker-compose.yml. Alternatively, copy the contents from the official repository. - Edit environment variables. Open the compose file with
nano docker-compose.yml. SetPANGOLIN_DOMAINto your chosen domain (e.g.,pangolin.example.com), and setACME_EMAILto your email for Let’s Encrypt certificates. Save and exit. - Start the stack. Run
docker compose up -d. This pulls images for Pangolin, its database (Postgres), and a few helper services. Wait a minute or two for everything to initialize. - Access the web UI. Open
https://pangolin.example.comin your browser. You’ll see a setup screen. Create an admin account (email and password). - Add a site (the remote machine). In the Pangolin dashboard, go to “Sites� and click “New Site�. Give it a name (e.g., “home-pi�). You’ll get a configuration token—copy it; you’ll need it on the remote device.
- Install Newt on the remote device. On the remote machine (e.g., Raspberry Pi), create a directory:
mkdir -p ~/newt && cd ~/newt. Create adocker-compose.ymlwith the Newt image:fosrl/newt:latest. Mount a volume for config, and set the environment variableNEWT_TOKENto the token from step 8. - Start Newt. Run
docker compose up -don the remote device. Check logs withdocker logs newt(or the container name) to see if it connects successfully. You should see a message like “connected to server�. - Create a route in Pangolin. Back in the dashboard, go to “Routes�. Click “New Route�. Select the site you created in step 8, choose the protocol (HTTP or TCP), and specify the target: for HTTP, enter
localhost:8080if your service runs on port 8080 on the remote device. For TCP, you can forward any port (e.g., SSH on 22). - Assign a domain. In the route settings, set the public domain (e.g.,
service.example.com) and choose whether to enable TLS (Let’s Encrypt will issue a certificate automatically). Save the route. - Test the connection. Open
https://service.example.comin your browser. If you set up an HTTP route, you should see your service. For TCP, test with a client (e.g.,ssh -p 2222 user@service.example.comif you forwarded SSH on port 2222).
Common Mistakes
- DNS not propagated: Trying to access the UI before DNS resolves will cause certificate errors. Wait and check with
dig pangolin.example.com. - Wrong token: Copying the token with extra spaces or line breaks breaks authentication. Paste it carefully or use a text editor to trim.
- Firewall blocking ports: Ensure ports 80 and 443 are open on your server’s firewall (ufw, iptables, or cloud security groups). Newt uses outbound connections, so remote devices usually need no inbound ports.
- Using HTTP instead of HTTPS: Pangolin expects to serve over HTTPS. If you set
PANGOLIN_DOMAINwithout a valid cert, the UI may not load. Let’s Encrypt handles this automatically if DNS is correct. - Forgetting to update the remote device’s Newt: Newt updates frequently. Pull new images with
docker compose pull && docker compose up -dto avoid compatibility issues.
Tips
- Use a wildcard DNS record (
*.example.com) to simplify adding new routes—Pangolin can automatically request certificates for subdomains. - Keep your server time synchronized (e.g., with NTP) to avoid certificate validation issues.
- Back up your Pangolin database (the Postgres volume) regularly. You can use
docker compose exec db pg_dump -U pangolin pangolin > backup.sql. - For TCP routes, remember to set the correct external port in the route configuration—it can be different from the internal port.
- Monitor logs with
docker compose logs -fon both server and remote to see connection status and errors.
Troubleshooting
- Newt won’t connect: Check the token (step 8) and that the server is reachable. Test with
curl -v https://pangolin.example.comfrom the remote device. If that fails, it’s a network issue—check outbound firewall on the remote. - Certificate errors in browser: Ensure DNS points to the correct server. If you changed the domain, restart Pangolin with
docker compose restartand check logs for ACME errors. - Route shows “offline�: The remote Newt might be disconnected. Check its logs for “connection lost� and restart it. Also verify the site is still enabled in Pangolin.
- HTTP service returns 502: The target (e.g.,
localhost:8080) is not reachable from the remote device. Confirm the service is running and listening on the correct interface (use0.0.0.0if needed). - Port 80/443 already in use: If another web server runs on the server, stop it or change Pangolin’s port mapping in the compose file (e.g.,
80:8080), but then you must add a reverse proxy yourself—simpler to free the ports.
Frequently Asked Questions
What exactly does Pangolin do?
Pangolin is a self-hosted reverse proxy with a web UI. It manages TLS certificates, routes, and authentication for your services. It works with Newt, a lightweight agent that runs on remote machines, to create secure tunnels without opening ports on those machines.
Do I need a static IP on the remote site?
No. Newt initiates an outbound connection to your Pangolin server, so the remote device can be behind NAT, have a dynamic IP, or be on a cellular network. Only the server needs a public IP.
Can I expose multiple services on one remote site?
Yes. In Pangolin, you create multiple routes, each pointing to the same site but with different target ports or hostnames. For example, route A forwards service1.example.com to localhost:3000 on the remote, and route B forwards service2.example.com to localhost:8080.
Is Pangolin free to use?
Pangolin is open-source (AGPL-3.0) and free to self-host. You only pay for your own server and domain. There is no built-in licensing fee.
How do I update Pangolin and Newt?
On the server, run docker compose pull && docker compose up -d. On each remote device, do the same in the Newt directory. Check the release notes for breaking changes before updating.
Can I use Pangolin for TCP services like SSH or Minecraft?
Yes. Create a TCP route in Pangolin, specify the internal port on the remote device, and choose an external port (or use the same). Then connect to yourdomain.com:externalport from anywhere.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Secure Boot Battlefield 6 ASUS: Fix & Enable Guide
- Best Tech Websites to Follow for Pros & Beginners
- Second Wind Quest Walkthrough: Where Winds Meet6.00 min/km
- Enshrouded Weapon Upgrade Guide: How to Improve Gear5.00 min/km
- Connect Phone to Controller for Cloud Gaming
- Python Search Highlighting: Snippets & Matches