refactor(env): explicit defaults.env with placeholders; drop auto-injection
A service/job's env is now exactly its defaults.env — castle injects no hidden
convention vars. Values support ${port}/${data_dir}/${name} placeholders
(resolved at deploy, alongside ${secret:…}), so a program's own env var names
map to castle's computed values without hardcoding.
Why: the auto-injected <PREFIX>_PORT/<PREFIX>_DATA_DIR were a guess at the
program's env names — right for castle-scaffolded services, dead weight for
adopted ones (lakehouse carried two dead vars; notification-bridge/backup jobs
too). They also weren't visible in the config editor (computed at deploy), which
was the source of the 'four env vars but the UI shows none' mystery.
- core: resolve_env_vars gains a context (${port}/${data_dir}/${name});
deploy builds env from defaults.env only — no <PREFIX>_* injection, no
port_env. Removed the port_env field and the dead _env_prefix helper.
- cli: 'service/job create' gains repeatable --env KEY=VALUE (replaces
--port-env); 'program create' scaffolds <PREFIX>_PORT/_DATA_DIR: ${…} for new
daemons.
- app: removed the 'Port env' field; the Environment editor (defaults.env) is
the single place, with a placeholder hint.
- live migration: central-context/castle-api/power-graph/protonmail mapped their
real vars explicitly; lakehouse → just LAKEHOUSED_DAEMON_PORT: ${port}, data
stays in ~/.lakehoused. Verified all services healthy on their ports, dead
vars gone, zero failed units.
- docs: registry.md/design.md/stack guides + findings updated to the explicit
model.
core 94 / cli 24 / api 52 green; ruff + app build clean.
This commit is contained in:
@@ -129,16 +129,21 @@ services:
|
||||
systemd: {}
|
||||
```
|
||||
|
||||
Convention-based env vars (`MY_SERVICE_DATA_DIR`, `MY_SERVICE_PORT`) are
|
||||
generated automatically by `castle deploy`. Only non-convention values
|
||||
need `defaults.env`:
|
||||
The env a service runs with is exactly what's in `defaults.env` — castle injects
|
||||
nothing implicitly. Map the vars your settings read (above, `env_prefix:
|
||||
"MY_SERVICE_"` → `MY_SERVICE_PORT`/`MY_SERVICE_DATA_DIR`) to castle's computed
|
||||
values with the `${port}`/`${data_dir}` placeholders:
|
||||
|
||||
```yaml
|
||||
defaults:
|
||||
env:
|
||||
MY_SERVICE_PORT: ${port} # = expose.http.internal.port
|
||||
MY_SERVICE_DATA_DIR: ${data_dir} # = $CASTLE_DATA_DIR/my-service
|
||||
CENTRAL_CONTEXT_URL: http://localhost:9001
|
||||
```
|
||||
|
||||
`castle program create` scaffolds the `${port}`/`${data_dir}` lines for you.
|
||||
|
||||
## Application entry point
|
||||
|
||||
```python
|
||||
@@ -305,8 +310,9 @@ $CASTLE_DATA_DIR/my-service/ # default /data/castle/my-service/
|
||||
└── item-name.meta.json
|
||||
```
|
||||
|
||||
The service receives this path via the generated `<PREFIX>_DATA_DIR` env var —
|
||||
it never hardcodes it. Use the `data_dir` setting from your config.
|
||||
The service receives this path via its `<PREFIX>_DATA_DIR` env var, which
|
||||
`defaults.env` maps from `${data_dir}` — it never hardcodes it. Use the
|
||||
`data_dir` setting from your config.
|
||||
|
||||
```python
|
||||
# storage.py
|
||||
|
||||
Reference in New Issue
Block a user