Domain Manager API¶
⚠️ CRITICAL: All domain configuration MUST be done via the REST API. Direct database access is STRICTLY FORBIDDEN.
Overview¶
Domain Manager is the centralized service for managing DNS records, Traefik routing, and SSL certificates across CharlieHub. It runs on hub2 and:
- Syncs domain configurations to OVH DNS API
- Auto-generates Traefik configuration for routing
- Manages SSL certificates with Let's Encrypt
- Provides real-time health checking and failover capabilities
- Validates configuration and prevents conflicts
All operations must go through the REST API. The database is internal and must never be accessed directly.
API Access¶
Location¶
| Context | URL |
|---|---|
| Internal (hub2) | http://localhost:8001/api/ |
| Web UI | https://domains.charliehub.net (requires Authelia auth) |
| Documentation | This page |
Authentication¶
All API calls require the X-API-Key header with a valid API key.
To get the current API key from hub2:
ssh hub2
sudo -i
cd /opt/charliehub
docker compose exec -T domain-manager env | grep API_KEY
Copy the value from the output. Example:
API_KEY=YOUR_API_KEY_HERE
Domain Operations¶
List All Domains¶
curl -s -H "X-API-Key: YOUR_API_KEY" http://localhost:8001/api/domains | jq .
Returns an array of all configured domains with their routing and status information.
Get Specific Domain¶
curl -s -H "X-API-Key: YOUR_API_KEY" \
http://localhost:8001/api/domains/123 | jq .
Create New Domain¶
curl -X POST http://localhost:8001/api/domains \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "example.charliehub.net",
"service_type": "http",
"environment": "production",
"backend_host": "10.44.1.100",
"backend_port": 8080,
"cors_enabled": false,
"ddns_enabled": false
}'
Response (201 Created):
{
"success": true,
"domain_id": 42,
"message": "Domain created successfully"
}
Update Existing Domain¶
curl -X PUT http://localhost:8001/api/domains/123 \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"backend_host": "10.44.1.200",
"backend_port": 9000
}'
You only need to include fields you want to change.
Delete Domain¶
curl -X DELETE http://localhost:8001/api/domains/123 \
-H "X-API-Key: YOUR_API_KEY"
This removes the domain configuration and updates DNS/Traefik automatically.
Deploy Changes¶
After creating or updating domains, deploy them:
curl -X POST http://localhost:8001/api/deploy-all \
-H "X-API-Key: YOUR_API_KEY"
This triggers: 1. Traefik configuration regeneration 2. OVH DNS API updates 3. Let's Encrypt certificate provisioning 4. Health check initialization
Domain Configuration¶
Available Fields¶
| Field | Required | Type | Options/Range | Description |
|---|---|---|---|---|
domain |
Yes | string | FQDN | Fully qualified domain name (e.g., service.charliehub.net) |
service_type |
Yes | string | http, api, spa, proxy, websocket, static, tcp-proxy, internal, manual |
Type of service; manual = externally managed |
environment |
Yes | string | production, development |
Environment tier |
backend_host |
Yes¹ | string | IP or hostname | Backend server address |
backend_port |
Yes¹ | int | 1-65535 | Backend port number |
cors_enabled |
No | bool | true/false | Enable CORS middleware |
cors_origin |
No | string | URL | CORS allowed origin |
default_path |
No | string | Path | Default redirect path (e.g., /app) |
auth_required |
No | bool | true/false | Require Authelia authentication (default: true) |
ddns_enabled |
No | bool | true/false | Enable DDNS sync to OVH |
ssl_enabled |
No | bool | true/false | Enable SSL (default: true) |
health_check_path |
No | string | Path | Health check endpoint |
¹ Required only if service_type is not manual
Service Types¶
http- Standard HTTP/HTTPS web serviceapi- REST API endpoint with optimized timeout settingsspa- Single Page Application (with asset caching)proxy- Transparent proxy to backendwebsocket- WebSocket endpointstatic- Static file servertcp-proxy- TCP-level proxy (non-HTTP)internal- Internal-only service (no external DNS)manual- Externally managed (no auto-configuration)
Authentication Control¶
By default, all domains require Authelia authentication for access. To disable authentication and allow public/unauthenticated access:
curl -X PUT http://localhost:8001/api/domains/123 \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"auth_required": false
}'
Current Unauthenticated Services: - 🔓 control.trevarn.com - UniFi management interface (internal network) - 🔓 brand.trevarn.com - Public branding portal - 🔓 isp.charliehub.net - ISP monitoring dashboard (public)
When auth_required: false, Traefik skips the Authelia middleware but still applies security headers (CSP, X-Frame-Options, etc.).
Python Examples¶
Simple Domain Listing¶
import requests
API_KEY = "your_key_here"
headers = {'X-API-Key': API_KEY}
response = requests.get(
'http://localhost:8001/api/domains',
headers=headers
)
for domain in response.json():
print(f"{domain['domain']}: {domain['backend_host']}:{domain['backend_port']}")
Create and Deploy¶
import requests
API_KEY = "your_key_here"
headers = {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
}
# Create new domain
new_domain = {
"domain": "files.charliehub.net",
"service_type": "http",
"environment": "production",
"backend_host": "10.44.1.117",
"backend_port": 8080,
"cors_enabled": False,
"ddns_enabled": False
}
response = requests.post(
'http://localhost:8001/api/domains',
json=new_domain,
headers=headers
)
if response.status_code == 201:
domain_id = response.json()['domain_id']
print(f"✓ Created domain ID {domain_id}")
# Deploy to OVH & Traefik
deploy = requests.post(
'http://localhost:8001/api/deploy-all',
headers=headers
)
print(f"✓ Deployed (status: {deploy.status_code})")
else:
print(f"✗ Error: {response.text}")
Important: Database Access Forbidden¶
Why Direct Database Access is Forbidden¶
The database is strictly for internal use only. Direct modifications:
❌ Bypass validation - No conflict checking, invalid configurations accepted
❌ Won't sync to OVH DNS - Domain won't be resolvable
❌ Won't regenerate Traefik configs - Routing won't work
❌ Break health checks - Monitoring and failover won't function
❌ Can corrupt the system - Orphaned records, dangling references
Database Location (DO NOT ACCESS)¶
Host: charliehub-postgres (Docker internal)
Database: charliehub_domains
User: charliehub
This is monitored. Direct access will be detected and rolled back.
Troubleshooting¶
API Not Responding?¶
ssh hub2
sudo -i
cd /opt/charliehub
# Check service status
docker compose ps domain-manager
# View logs
docker compose logs -f domain-manager
Configuration Not Deploying?¶
Check Traefik logs:
docker compose logs -f charliehub-traefik | grep -i error
Check DDNS/OVH sync logs:
docker compose logs -f charliehub_ddns_v2
Domain Not Resolvable?¶
Verify in OVH API (wait 5-10 minutes for propagation):
dig your-domain.charliehub.net +short
Health Check Failures?¶
Check backend service is actually running and responding to configured port.
Common Mistakes¶
❌ Trying to Access Database¶
psql -h charliehub-postgres -U charliehub -d charliehub_domains
DON'T DO THIS. Use the API instead.
❌ Using Wrong API Key¶
curl -H "API-Key: wrong_key" http://localhost:8001/api/domains
The header must be X-API-Key, and use the correct key from docker compose exec -T domain-manager env | grep API_KEY.
❌ Missing Content-Type Header¶
curl -X POST http://localhost:8001/api/domains \
-H "X-API-Key: YOUR_API_KEY" \
-d '{"domain": "..."}'
Always include -H "Content-Type: application/json" for POST/PUT requests.
❌ Forgetting to Deploy¶
Creating a domain doesn't automatically deploy it. You must:
curl -X POST http://localhost:8001/api/deploy-all \
-H "X-API-Key: YOUR_API_KEY"
Support¶
For issues or questions:
- Check the logs:
docker compose logs domain-manager - Review your API request - ensure all required fields are present
- Verify backend service is running on the configured host/port
- Check DNS propagation (up to 10 minutes for changes)
Always use the API. Never access the database directly.
Last updated: 2026-02-08 | For latest info: https://docs.charliehub.net