# Tunnel Management (Pangolin) The Tunnel Management feature provides secure public access to your self-hosted Changemaker Lite instance via Pangolin tunnel service with Newt container integration. An alternative to Cloudflare Tunnel for exposing your application to the internet. ## Overview Pangolin integration provides: - **Secure Tunneling** - Expose localhost to public internet - **Newt Container** - Self-hosted exit node - **Setup Wizard** - Guided configuration - **Resource Management** - Subdomain and route configuration - **Status Monitoring** - Tunnel health and uptime - **No DNS Configuration** - Automatic subdomain setup ## Features ### Tunnel Setup - Create Pangolin organization and site - Generate Newt container credentials - Configure resources (subdomains) - Deploy Newt container - Start tunnel automatically ### Resource Configuration Map internal services to public subdomains: - `app.yoursite.com` → Admin GUI (port 3000) - `api.yoursite.com` → Express API (port 4000) - `media.yoursite.com` → Media API (port 4100) - `docs.yoursite.com` → MkDocs (port 4003) - `grafana.yoursite.com` → Grafana (port 3001) - Custom subdomains for other services ### Admin Interface Setup wizard (`/app/services/pangolin`): 1. **Connection** - Enter Pangolin API credentials 2. **Organization** - Create/select organization 3. **Site** - Create/configure site 4. **Resources** - Map services to subdomains 5. **Deploy** - Start Newt container 6. **Verify** - Test tunnel connectivity ### Status Monitoring - Tunnel status (active/inactive) - Resource health checks - Traffic statistics - Error logs - Quick actions (restart, update config) ## Architecture ### Backend Components **Pangolin Client:** - `api/src/services/pangolin.client.ts` - Typed HTTP client - API key authentication - Full Integration API coverage **Pangolin Module:** - `api/src/modules/pangolin/pangolin.routes.ts` - Admin endpoints - Setup, config, status routes **Newt Container:** - Docker service in `docker-compose.yml` - Self-hosted exit node - Routes through nginx - Automatic startup ### Frontend Components **Admin Page:** - `admin/src/pages/PangolinPage.tsx` - Setup wizard - Step-by-step configuration - Status dashboard - Resource table ### Docker Integration Newt container in `docker-compose.yml`: ```yaml newt: image: bnkserve/newt:latest container_name: newt restart: unless-stopped depends_on: - nginx environment: NEWT_ID: ${PANGOLIN_NEWT_ID} NEWT_SECRET: ${PANGOLIN_NEWT_SECRET} PANGOLIN_ENDPOINT: ${PANGOLIN_ENDPOINT} networks: - changemaker-lite ``` ## Configuration ### Environment Variables ```bash # Pangolin API PANGOLIN_API_URL=https://api.bnkserve.org/v1 PANGOLIN_API_KEY=your_api_key # Organization & Site PANGOLIN_ORG_ID=your_org_id PANGOLIN_SITE_ID=your_site_id # Newt Container PANGOLIN_NEWT_ID=your_newt_id PANGOLIN_NEWT_SECRET=your_newt_secret PANGOLIN_ENDPOINT=your_endpoint_url ``` ### Setup Process 1. **Create Account** - Sign up at pangolin.bnkserve.org 2. **Get API Key** - Generate API key in dashboard 3. **Add to .env** - Set `PANGOLIN_API_KEY` 4. **Run Wizard** - Complete setup wizard in admin 5. **Deploy Newt** - Start Newt container 6. **Test Tunnel** - Verify public access ## Pangolin API Integration ### API Client Usage ```typescript import { pangolinClient } from '../services/pangolin.client'; // Get organization const org = await pangolinClient.getOrganization(orgId); // Create site const site = await pangolinClient.createSite(orgId, { name: 'My Campaign Site', domain: 'campaign.example.com', }); // Create resource (subdomain) const resource = await pangolinClient.createResource(siteId, { subdomain: 'app', targetUrl: 'http://nginx:80', port: 80, }); // Get tunnel status const status = await pangolinClient.getTunnelStatus(siteId); ``` ### Authentication Pangolin uses Bearer token authentication: ```typescript const headers = { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }; ``` ## Setup Wizard ### Step 1: Connection - Enter Pangolin API key - Validate credentials - Test connection ### Step 2: Organization - List existing organizations - Create new organization - Select organization ### Step 3: Site - List existing sites - Create new site - Configure domain - Select site ### Step 4: Resources - Add resources (subdomains) - Map to internal services - Configure routing Example resources: ``` app.yoursite.com → http://nginx:80 (proxies to admin:3000) api.yoursite.com → http://nginx:80 (proxies to api:4000) ``` ### Step 5: Deploy - Generate Newt credentials - Update .env with credentials - Restart Newt container - Verify tunnel ### Step 6: Verify - Test public URLs - Check resource health - View status dashboard ## Newt Container ### Purpose Newt is the exit node that: - Establishes tunnel to Pangolin - Receives public traffic - Forwards to internal nginx - Handles SSL/TLS termination ### Routing All traffic flows through nginx: ``` Public Request ↓ Pangolin Tunnel ↓ Newt Container ↓ Nginx (port 80) ↓ Internal Service (admin/api/etc.) ``` ### Configuration Newt configured via environment variables: - `NEWT_ID` - Unique container identifier - `NEWT_SECRET` - Authentication secret - `PANGOLIN_ENDPOINT` - Tunnel endpoint URL ## Resource Management ### Resource Types - **Web Apps** - Admin, public pages - **APIs** - Express API, Media API - **Services** - Docs, Grafana, etc. ### Subdomain Mapping ```typescript interface Resource { subdomain: string; // 'app', 'api', 'docs' targetUrl: string; // 'http://nginx:80' port: number; // 80 protocol: string; // 'http' or 'https' } ``` ### Internal Routing Nginx routes by Host header: ```nginx server { listen 80; server_name app.yoursite.com; location / { proxy_pass http://admin:3000; } } server { listen 80; server_name api.yoursite.com; location / { proxy_pass http://api:4000; } } ``` ## Status Dashboard ### Tunnel Status Display: - Active/inactive status - Uptime duration - Last connected time - Connection errors ### Resource Health For each resource: - Subdomain - Target service - Health status (online/offline) - Response time - Error count ### Actions Quick actions: - Restart tunnel - Update configuration - Add/remove resources - Test connectivity - View logs ## Security ### SSL/TLS - Pangolin handles SSL termination - Automatic certificate management - HTTPS enforced on public URLs - HTTP → HTTPS redirect ### Authentication - API key authentication - Newt secret for container auth - No public credentials exposure ### Access Control - Firewall rules (optional) - IP whitelisting (optional) - Rate limiting via Pangolin - DDoS protection ## Troubleshooting ### Connection Issues 1. Verify API key 2. Check organization/site IDs 3. Confirm Newt credentials 4. Test internal nginx routing 5. Check container logs ### Resource Not Accessible 1. Verify resource configuration 2. Test internal service 3. Check nginx config 4. Review Pangolin logs 5. Confirm DNS propagation ### Newt Container Errors 1. Check environment variables 2. Verify network connectivity 3. Review container logs 4. Restart container 5. Update Newt image ## API Endpoints ### Admin Endpoints ``` GET /api/pangolin/status # Tunnel status GET /api/pangolin/config # Current configuration GET /api/pangolin/organizations # List organizations GET /api/pangolin/sites # List sites GET /api/pangolin/resources # List resources POST /api/pangolin/setup # Complete setup wizard POST /api/pangolin/sync # Sync configuration ``` ## Comparison to Cloudflare Tunnel ### Advantages - Self-hosted exit node (Newt) - No vendor lock-in - Full control over routing - Open-source alternative - No DNS changes required ### Considerations - Requires Pangolin account - Newt container overhead - Manual setup process - Smaller ecosystem ## Related Documentation - [Pangolin Page](../../frontend/pages/admin/pangolin-page.md) - [Pangolin Client](../../backend/services/index.md) - [Tunneling Deployment](../../deployment/tunneling.md) - [Nginx Configuration](../../deployment/nginx.md) - [SSL/TLS Setup](../../deployment/ssl-tls.md) - [Docker Compose](../../deployment/docker-compose.md)