Brings up the whole platform behind a single Caddy entrypoint so the
routing topology can be exercised end-to-end before any feature code
lands. Same Caddyfile shape (admin / data plane / dashboard) maps to
single-process MVP today and will map to cluster mode later by
swapping the upstream lists, not by restructuring the proxy.
* caddy/Caddyfile — dev: HTTP only, picloud and dashboard upstreams
by service name. caddy/Caddyfile.prod — Let's Encrypt for
PICLOUD_DOMAIN with PICLOUD_ADMIN_EMAIL.
* docker/orchestrator.Dockerfile — multi-stage build of the
`picloud` all-in-one against the pinned 1.92 toolchain; debian
slim runtime, non-root user, /healthz HEALTHCHECK.
* docker/dashboard.Dockerfile — node:24-alpine builder + caddy
runtime that serves the static SPA with SPA fallback.
* docker-compose.yml — postgres + picloud + dashboard + caddy,
Caddy exposed on host :8000 (configurable), Postgres on :15432
(loopback only). Health-gated startup ordering.
* docker-compose.prod.yml — overlay: removes Postgres host
mapping, expands Caddy to 80/443/443udp, swaps Caddyfile.prod,
adds restart policy.
* .env.example documents every knob the compose stack reads.
Verified via `docker compose up -d`:
* `curl :8000/healthz` → 200 ok (orchestrator)
* `curl :8000/api/admin/scripts` → 404 (manager, routed correctly)
* `curl :8000/api/execute/<id>` → 404 (orchestrator, routed correctly)
* `curl :8000/` → SPA index served (dashboard via Caddy)
* `curl :8000/favicon.svg` → 200 image/svg+xml
* Postgres healthy and reachable on 127.0.0.1:15432.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.2 KiB
Caddyfile
52 lines
1.2 KiB
Caddyfile
# PiCloud dev Caddyfile.
|
|
#
|
|
# Same routing shape as prod, with two differences:
|
|
# - bound to plain HTTP (no domain, no automatic TLS)
|
|
# - upstreams are the docker-compose service names
|
|
#
|
|
# Control plane (`/api/admin/*`) and data plane (`/api/execute/*`, `/exec/*`)
|
|
# both terminate on the `picloud` all-in-one for now; in cluster mode the
|
|
# data-plane handles will list multiple orchestrator upstreams here while
|
|
# the admin handle still points at a single manager.
|
|
{
|
|
auto_https off
|
|
admin off
|
|
log {
|
|
output stdout
|
|
format console
|
|
}
|
|
}
|
|
|
|
:80 {
|
|
# Health probes go straight to the orchestrator.
|
|
handle /healthz {
|
|
reverse_proxy picloud:8080
|
|
}
|
|
|
|
# Control plane → manager (single-process: picloud).
|
|
handle /api/admin/* {
|
|
reverse_proxy picloud:8080
|
|
}
|
|
|
|
# Data plane → orchestrator (single-process: picloud).
|
|
handle /api/execute/* {
|
|
reverse_proxy picloud:8080
|
|
}
|
|
handle /exec/* {
|
|
reverse_proxy picloud:8080
|
|
}
|
|
|
|
# Everything else → dashboard SPA (Caddy serves a self-contained
|
|
# dashboard container that already runs file_server with index.html
|
|
# fallback for client-side routing).
|
|
handle {
|
|
reverse_proxy dashboard:80
|
|
}
|
|
|
|
log {
|
|
output stdout
|
|
format console
|
|
}
|
|
}
|