install.sh: bootstrap Castle's own control plane

A fresh clone + ./install.sh set up the infra (Docker, Caddy, MQTT,
Postgres) but left the registry empty — so `castle deploy && castle
start` brought up nothing. install.sh now gets a person all the way to
a running Castle:

- ensure_uv + install_cli: install uv and the `castle` CLI (editable
  from ./cli) so the command exists on a fresh machine.
- seed_control_plane: register castle-gateway, castle-api, and the
  castle dashboard from a new bootstrap/ seed dir, and add `repo:` to
  castle.yaml so `source: repo:<name>` resolves. Never clobbers
  existing entries.
- build_dashboard: build app/dist/ so the gateway has a UI to serve
  (best-effort; warns if pnpm is absent).

The gateway seed uses a `__SPECS_DIR__` placeholder (no machine-specific
paths in the repo), substituted with this machine's specs dir at seed
time. .gitignore negates bootstrap/**/castle.yaml so the seeds are
tracked despite the user-registry ignore rule.

Verified: seeded config loads, derives kinds service/service/static,
and renders an off-mode Caddyfile serving the dashboard at :9000/ with
/api/* proxied to castle-api.
This commit is contained in:
2026-07-01 16:33:42 -07:00
parent 442b1692d9
commit d34ff9220d
7 changed files with 145 additions and 2 deletions

1
.gitignore vendored
View File

@@ -5,4 +5,5 @@ __pycache__
.claude
node_modules
castle.yaml
!bootstrap/**/castle.yaml
.working