# Caddy config for WROLPi services (Docker). { # No ACME - WROLPi is designed for offline use. auto_https disable_redirects } :443 { tls /etc/ssl/caddy/cert.crt /etc/ssl/caddy/cert.key header Access-Control-Allow-Origin "*" header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" header Access-Control-Allow-Headers "Content-Type, Accept" handle /ca.crt { root * /opt/media/config/ssl header Content-Type "application/x-x509-ca-cert" header Content-Disposition "attachment; filename=\"wrolpi-ca.crt\"" file_server } handle /favicon.ico { root * /etc/caddy rewrite * /favicon.ico file_server } handle /apple-touch-icon.png { root * /etc/caddy rewrite * /icon.png file_server } # WebSocket for React dev server. handle /ws { reverse_proxy app:3000 } # Controller - system management API and UI. handle_path /controller/* { reverse_proxy controller:80 } handle /controller { redir * /controller/ 301 } # Speed test streams generated bytes; never buffer it. handle /api/speedtest/* { reverse_proxy api:8081 { flush_interval -1 } } # AI chat streams Server-Sent Events; never buffer them. handle /api/chat* { reverse_proxy api:8081 { flush_interval -1 } } # Main API. handle /api/* { reverse_proxy api:8081 } # WROLPi blobs (planet overview map, fonts, etc.) handle_path /blobs/* { root * /opt/wrolpi-blobs file_server } # Map static assets (fonts, sprites) for embedded MapLibre viewer. handle_path /map-assets/* { root * /opt/wrolpi/modules/map/static file_server } # Custom MIME types not in Caddy's defaults. @yaml path *.yaml *.yml header @yaml Content-Type "text/yaml" @epub path *.epub header @epub Content-Type "application/epub+zip" @mobi path *.mobi header @mobi Content-Type "application/x-mobipocket-ebook" # Static media files with directory browsing. handle_path /media/* { root * /opt/media header Content-Disposition "inline" file_server browse } handle /media { redir * /media/ 301 } # Downloads with Content-Disposition header. handle_path /download/* { root * /opt/media header Content-Disposition "attachment" file_server browse } handle /download { redir * /download/ 301 } # React app with fallback to Controller. handle { reverse_proxy app:3000 } handle_errors 502 503 504 { redir * "http://{host}:8080/?fallback=true" 302 } } # Kiwix HTTPS proxy (replaces zim_https container). :8085 { tls /etc/ssl/caddy/cert.crt /etc/ssl/caddy/cert.key header ?Access-Control-Allow-Origin "*" header ?Access-Control-Allow-Methods "GET, OPTIONS" reverse_proxy zim:80 } # Help HTTPS proxy (replaces help_https container). :8086 { tls /etc/ssl/caddy/cert.crt /etc/ssl/caddy/cert.key header ?Access-Control-Allow-Origin "*" header ?Access-Control-Allow-Methods "GET, OPTIONS" reverse_proxy help:80 } # Map viewer - serves MapLibre static assets and PMTiles data via Caddy. :8084 { tls /etc/ssl/caddy/cert.crt /etc/ssl/caddy/cert.key header ?Access-Control-Allow-Origin "*" header ?Access-Control-Allow-Methods "GET, HEAD, OPTIONS" header ?Access-Control-Expose-Headers "Content-Range, Content-Length" # PMTiles file list from WROLPi API. handle /api/map/* { reverse_proxy api:8081 } # WROLPi blobs (planet overview map). handle_path /blobs/* { root * /opt/wrolpi-blobs file_server } # PMTiles data files from media directory (Range Requests supported by default). handle_path /data/* { root * /opt/media/map file_server } # MapLibre static assets (HTML, JS, CSS, fonts, sprites). handle { root * /opt/wrolpi/modules/map/static file_server } }