Skip to content

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 service
  • api - REST API endpoint with optimized timeout settings
  • spa - Single Page Application (with asset caching)
  • proxy - Transparent proxy to backend
  • websocket - WebSocket endpoint
  • static - Static file server
  • tcp-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:

  1. Check the logs: docker compose logs domain-manager
  2. Review your API request - ensure all required fields are present
  3. Verify backend service is running on the configured host/port
  4. 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