# PiCloud dev Caddyfile. # # Routing topology: # /healthz, /version → picloud (liveness + version, k8s-friendly) # /api/v1/admin/* → picloud (manager control plane) # /api/v1/execute/{id} → picloud (orchestrator ID-based bypass) # /api/* → 404 (unsupported / sunset API version) # /admin/* → dashboard SPA (mounted with paths.base=/admin) # everything else → picloud (orchestrator route table; user paths) # # The "everything else → picloud" rule is what makes user-defined paths # like /greet possible. picloud's matcher answers them via the routes # table, or returns 404 with a precise JSON error. # # When v2 of the API ships, add `handle /api/v2/admin/* { ... }` etc. # alongside the v1 handles, before the catch-all `/api/*` 404. { auto_https off admin off log { output stdout format console } } :80 { handle /healthz { reverse_proxy picloud:8080 } handle /version { reverse_proxy picloud:8080 } handle /api/v1/admin/* { reverse_proxy picloud:8080 } handle /api/v1/execute/* { reverse_proxy picloud:8080 } handle /api/* { respond 404 { body "{\"error\":\"no such API version — see /version for supported routes\"}" close } } # Dashboard SPA at /admin. Its internal Caddy serves files from /srv # (root); we don't strip the prefix because SvelteKit was built with # paths.base = '/admin' so the bundle's URLs already include it. handle /admin/* { reverse_proxy dashboard:80 } handle /admin { # Bare /admin (no trailing slash) — let SvelteKit's SPA handle it. reverse_proxy dashboard:80 } # Everything else → picloud's user-route fallback. If no route # matches, picloud responds 404 with a JSON body. handle { reverse_proxy picloud:8080 } log { output stdout format console } }