# Pangolin Tunnel Deployment ## Overview Pangolin is a self-hosted tunnel service (alternative to Cloudflare Tunnel) that provides public HTTPS access to your Changemaker Lite instance without port forwarding or firewall configuration. **Benefits:** - No port forwarding needed - SSL/TLS handled by tunnel provider - Static public URLs - Self-hosted tunnel server (privacy/control) - Free/open source **Architecture:** ``` Internet → Pangolin Tunnel (pangolin.bnkserve.org) → Newt Container → Nginx → Services ``` **Changemaker Integration:** - Pangolin server: https://api.bnkserve.org/v1 - Tunnel endpoint: https://pangolin.bnkserve.org - Newt container: Tunnel connector (fosrl/newt image) - Admin GUI: PangolinPage.tsx setup wizard --- ## Setup Workflow ### 1. Prerequisites **Required:** - Pangolin API key (obtain from Pangolin admin) - Docker Compose running - Nginx container accessible from Newt **Environment Variables:** ```bash PANGOLIN_API_URL=https://api.bnkserve.org/v1 PANGOLIN_API_KEY= PANGOLIN_ORG_ID= PANGOLIN_SITE_ID= PANGOLIN_ENDPOINT=https://pangolin.bnkserve.org PANGOLIN_NEWT_ID= PANGOLIN_NEWT_SECRET= ``` --- ### 2. Setup via Admin GUI **Easiest method:** Use `/app/pangolin` page in admin GUI. **Steps:** 1. Navigate to http://localhost:3000/app/pangolin 2. Enter `PANGOLIN_API_KEY` (click "Test Connection") 3. Create Organization (or select existing) 4. Create Site (linked to org) 5. Create Endpoint (tunnel URL) 6. Create Resource (Newt connector credentials) 7. Copy `NEWT_ID` and `NEWT_SECRET` to `.env` 8. Restart Newt container: `docker compose restart newt` --- ### 3. Manual Setup (CLI) **Organization:** ```bash curl -X POST https://api.bnkserve.org/v1/orgs \ -H "Authorization: Bearer $PANGOLIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "My Organization", "description": "Changemaker Lite Production" }' # Returns: # {"id":"org_abc123","name":"My Organization",...} export PANGOLIN_ORG_ID=org_abc123 ``` **Site:** ```bash curl -X POST https://api.bnkserve.org/v1/sites \ -H "Authorization: Bearer $PANGOLIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "org_id": "'"$PANGOLIN_ORG_ID"'", "name": "Production Site", "description": "Main deployment" }' # Returns: # {"id":"site_xyz789","name":"Production Site",...} export PANGOLIN_SITE_ID=site_xyz789 ``` **Endpoint:** ```bash curl -X POST https://api.bnkserve.org/v1/endpoints \ -H "Authorization: Bearer $PANGOLIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "site_id": "'"$PANGOLIN_SITE_ID"'", "subdomain": "changemaker", "domain": "pangolin.bnkserve.org" }' # Returns: # {"id":"endpoint_def456","url":"https://changemaker.pangolin.bnkserve.org",...} export PANGOLIN_ENDPOINT=https://changemaker.pangolin.bnkserve.org ``` **Resource (Newt Connector):** ```bash curl -X POST https://api.bnkserve.org/v1/resources \ -H "Authorization: Bearer $PANGOLIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "endpoint_id": "", "target": "http://nginx:80", "name": "Changemaker Services" }' # Returns: # {"id":"newt_abc123","secret":"secret_xyz789",...} export PANGOLIN_NEWT_ID=newt_abc123 export PANGOLIN_NEWT_SECRET=secret_xyz789 ``` **Update .env:** ```bash cat >> .env < \ -H "Authorization: Bearer $PANGOLIN_API_KEY" ``` **Common Causes:** - Resource target points to wrong service - Nginx not listening on port 80 - Firewall blocking Nginx → backend communication **Solution:** ```bash # Verify Nginx config docker compose exec nginx nginx -t # Check Nginx listening docker compose exec nginx netstat -tulpn | grep :80 # Test backend from Nginx docker compose exec nginx curl http://changemaker-v2-api:4000/api/health ``` --- ### SSL Certificate Errors **Symptoms:** Browser shows "Certificate invalid" warning **Cause:** Tunnel endpoint SSL certificate not trusted (rare). **Solution:** Contact Pangolin support — tunnel provider manages SSL certificates. --- ### Frequent Disconnects **Symptoms:** Newt reconnects every few minutes **Diagnosis:** ```bash # Check for network issues docker compose logs newt | grep -i disconnect # Monitor connection watch -n5 'docker compose logs --tail=1 newt' ``` **Possible Causes:** - Network instability - Container restarts (check `docker compose ps`) - Resource limits (check `docker stats newt-changemaker`) **Solution:** ```bash # Increase restart backoff (if needed) # Edit docker-compose.yml: newt: restart_policy: condition: on-failure delay: 5s max_attempts: 3 ``` --- ## Migration from Cloudflare Tunnel **Retired Scripts** (in `scripts/legacy/`): - `start-production.sh` - `config.sh` - `tunnel-config.sh` **Migration Steps:** 1. Stop Cloudflare tunnel: `cloudflared service uninstall` 2. Remove Cloudflare credentials: `rm ~/.cloudflared/*.json` 3. Setup Pangolin tunnel (see above) 4. Update DNS: Change CNAME from `cloudflared.com` to `pangolin.bnkserve.org` 5. Test new tunnel: `curl https://changemaker.pangolin.bnkserve.org/api/health` 6. Remove old scripts: `rm scripts/legacy/*` **Why Pangolin?** - Self-hosted (privacy/control) - No Cloudflare dependency - Free/open source - API-driven management --- ## Advanced Configuration ### Custom Tunnel Domain **Requirement:** Own domain with DNS control. **Steps:** 1. Create endpoint with custom domain 2. Add DNS record: `tunnel.cmlite.org CNAME pangolin.bnkserve.org.` 3. Update `PANGOLIN_ENDPOINT=https://tunnel.cmlite.org` 4. Restart Newt ### Multiple Sites **Use case:** Staging + production on same tunnel. **Setup:** ```bash # Create second site curl -X POST https://api.bnkserve.org/v1/sites \ -d '{"org_id":"...","name":"Staging"}' # Create endpoint for staging curl -X POST https://api.bnkserve.org/v1/endpoints \ -d '{"site_id":"...","subdomain":"staging-changemaker"}' # Create resource pointing to staging Nginx curl -X POST https://api.bnkserve.org/v1/resources \ -d '{"endpoint_id":"...","target":"http://nginx-staging:80"}' ``` --- ## Monitoring ### Health Checks **Tunnel status:** ```bash # Container health docker compose ps newt # Connection logs docker compose logs --tail=50 newt | grep -i connected # Test public endpoint curl -I https://changemaker.pangolin.bnkserve.org ``` **Prometheus metrics** (if enabled): ```bash # API uptime through tunnel curl https://changemaker.pangolin.bnkserve.org/api/metrics | grep cm_api_uptime ``` --- ## Related Documentation - **[Docker Compose](docker-compose.md)** — Newt container configuration - **[Nginx Configuration](nginx.md)** — Reverse proxy setup - **[SSL/TLS](ssl-tls.md)** — Certificate management (handled by tunnel) - **[Environment Variables](environment-variables.md)** — Pangolin env vars