# Caddyfile for HR AI Backend with automatic HTTPS # Environment variable DOMAIN will be used, defaults to localhost {$DOMAIN:localhost} { # Backend API routes handle /api/* { reverse_proxy backend:8000 } # Health check endpoint handle /health { reverse_proxy backend:8000 } # LiveKit WebSocket and HTTP endpoints handle /livekit/* { reverse_proxy livekit:7880 } # LiveKit WebSocket upgrade handle /rtc { reverse_proxy livekit:7880 } # Frontend (SPA) - serve everything else handle { reverse_proxy frontend:3000 # SPA fallback - serve index.html for all non-API routes @notapi { not path /api/* not path /health not path /livekit/* not path /rtc file { try_files {path} /index.html } } rewrite @notapi /index.html } # Enable gzip compression encode gzip # Security headers header { # HSTS Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # XSS Protection X-Content-Type-Options "nosniff" X-Frame-Options "DENY" X-XSS-Protection "1; mode=block" # CORS for API (adjust origins as needed) Access-Control-Allow-Origin "*" Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Access-Control-Allow-Headers "Content-Type, Authorization" } # Logging log { output file /var/log/caddy/access.log format json } } # Development/localhost configuration (no HTTPS) localhost { # Backend API routes handle /api/* { reverse_proxy backend:8000 } # Health check endpoint handle /health { reverse_proxy backend:8000 } # LiveKit endpoints handle /livekit/* { reverse_proxy livekit:7880 } handle /rtc { reverse_proxy livekit:7880 } # Frontend handle { reverse_proxy frontend:3000 @notapi { not path /api/* not path /health not path /livekit/* not path /rtc file { try_files {path} /index.html } } rewrite @notapi /index.html } encode gzip }