408 lines
8.2 KiB
Markdown

# 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)