Create Caddy API integration for dynamic reverse proxy routes.
Omni/Deploy/Caddy.py - Caddy admin API clientCaddy exposes admin API at localhost:2019 by default.
import requests as Requests
import json as Json
CADDY_ADMIN = "http://localhost:2019"
def build_route(service: Service) -> dict:
"""Build Caddy route config for a service."""
if not service.http:
return None
return {
"@id": f"biz-{service.name}",
"match": [{"host": [service.http.domain]}],
"handle": [{
"handler": "reverse_proxy",
"upstreams": [{"dial": f"localhost:{service.http.internalPort}"}]
}]
}
def get_current_routes() -> list:
"""Get current Caddy routes."""
resp = Requests.get(f"{CADDY_ADMIN}/config/apps/http/servers/srv0/routes")
return resp.json() if resp.ok else []
def upsert_route(service: Service):
"""Add or update route for service."""
route = build_route(service)
if not route:
return
route_id = f"biz-{service.name}"
# Try to update existing
resp = Requests.patch(
f"{CADDY_ADMIN}/id/{route_id}",
json=route,
headers={"Content-Type": "application/json"}
)
if not resp.ok:
# Add new route
Requests.post(
f"{CADDY_ADMIN}/config/apps/http/servers/srv0/routes",
json=route,
headers={"Content-Type": "application/json"}
)
def delete_route(service_name: str):
"""Remove route for service."""
Requests.delete(f"{CADDY_ADMIN}/id/biz-{service_name}")
def sync_routes(services: list[Service]):
"""Sync all routes from manifest."""
for service in services:
if service.http:
upsert_route(service)
{
admin localhost:2019
}
Caddy handles HTTPS automatically when domain is specified. No additional config needed.
bild --test Omni/Deploy/Caddy.py