408 lines
8.2 KiB
Markdown
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)
|