Problem: node and cross-cutting narratives lived at the repo root
(containers/, vms/, infrastructure/, host .md files), interleaved with the
machine-readable substrate.
Change:
- Move containers/ -> knowledge/wiki/containers/, vms/ -> knowledge/wiki/vms/,
infrastructure/ -> knowledge/wiki/infrastructure/, hosts/{hubris,strong}.md ->
knowledge/wiki/hosts/, infrastructure/references/ -> knowledge/sources/references/,
GLOSSARY.md -> knowledge/GLOSSARY.md.
- Add knowledge/{index.md,log.md,sources/index.md} scaffolding.
- Rewrite all relative links repo-wide via a path-resolving mapper (inbound +
outbound + between-moved-files), including .hermes/, runbooks, operations,
investigations, plans, README, AGENTS.
- Repoint inventory.yaml doc_page fields and regenerate hosts/*.yaml (which
embed doc_page); update oikos/gen-topology.py output path, candidate doc
paths, and footer links; update code-comment doc paths.
Substrate untouched in place: inventory.yaml, hosts/*.yaml (regenerated,
idempotent), oikos/ code, mcp/, secrets/, bin/.
Verification:
- Logical broken-link set identical to pre-move baseline (net 128 -> 127; the
topology regen fixed one, introduced none). Remaining are pre-existing refs
to destroyed/archived nodes, out of scope for this move.
- gen-topology.py --check exit 0 (in sync); cards carry knowledge/wiki/ doc paths.
- build_host_files.py idempotent; all inventory doc_page targets resolve.
- MCP contract verified: get_page/search_docs/get_changelog resolve moved pages.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
97 lines
4.9 KiB
Markdown
97 lines
4.9 KiB
Markdown
# Oikos Console — deploy notes
|
|
|
|
Deploys the same way `homelab-mcp` and `secrets-issuance` already do:
|
|
Shape B webhook (own checkout, own systemd units, own deploy secret) on
|
|
LXC 105 (apps), reading `HOMELAB_CONTEXT_DIR=/opt/homelab-context` for
|
|
all data. See [infrastructure/auto-deploy.md](../../../knowledge/wiki/infrastructure/auto-deploy.md)
|
|
for the general pattern; webhook ids 10 (homelab-mcp, :9811) and 11
|
|
(secrets-issuance, :9821) are the direct precedent — this is a third
|
|
webhook on `dtoro/Homelab-Docs`, port :9831.
|
|
|
|
## Status (2026-07-06)
|
|
|
|
- **Console deploy on apps (105): done.** Live at `/opt/oikos-console`,
|
|
both systemd units enabled and active, verified locally
|
|
(`127.0.0.1:8091` → `200`) and end-to-end
|
|
(`https://oikos.hubris.network/` → `302`, the Authentik gate firing).
|
|
- **Gitea webhook: registered but NOT currently working.** Webhook id
|
|
**14** (`http://192.168.8.205:9831/deploy`, `push` events, `main`
|
|
branch filter, active) exists, and its secret is synced correctly
|
|
between Gitea and `/etc/oikos-console-deploy/secret` on apps (rotated
|
|
once to fix a drift from an earlier partial-PATCH update) — but
|
|
deliveries still 403 with a signature mismatch for a cause not yet
|
|
found. **Until this is fixed, `git push` to `main` will NOT
|
|
auto-redeploy the console** — run `deploy.sh` manually on apps after
|
|
any change (see "One-time setup" below; it's idempotent, safe to
|
|
re-run). Debugging this further needs either a git-committed (not
|
|
ad-hoc SSH-edited) debug build of `webhook.py`, or checking Gitea's
|
|
actual signing behavior against a captured raw request — both stalled
|
|
on safety-classifier blocks around production code edits and
|
|
credential handling this session, so left for a future pass.
|
|
- **Caddy route: done.** Pushed to `dtoro/caddy-conf` (commit `c195142`),
|
|
Authentik-gated matching `paperless.hubris.network`'s pattern, reload
|
|
confirmed clean (an unrelated route stayed healthy through the reload).
|
|
**Found and fixed a real bug while wiring this up:** `oikos-console.service`
|
|
originally bound `127.0.0.1` only — since Caddy runs on a *different*
|
|
host (LXC 121), that would have made the console completely
|
|
unreachable once deployed. Now binds `0.0.0.0`, matching `homelab-mcp`'s
|
|
convention (trust boundary is LAN/mesh + the Authentik gate, not the
|
|
bind address).
|
|
- **DNS entry: done.** `oikos.hubris.network` A record added via
|
|
Technitium's REST API (login → createToken → zones/records/add, all
|
|
in one in-memory call; the session/API token was never printed or
|
|
written to disk, and wasn't persisted anywhere after the call
|
|
completed). Verified: `dig @192.168.8.2 +short oikos.hubris.network`
|
|
→ `192.168.8.175`.
|
|
|
|
## One-time setup on apps (105)
|
|
|
|
```bash
|
|
git clone https://git.hubris.network/dtoro/Homelab-Docs.git /opt/oikos-console
|
|
cd /opt/oikos-console
|
|
./oikos/console/deploy/deploy.sh # first install
|
|
./oikos/console/deploy/webhook/install.sh # generates a NEW secret by default —
|
|
# see "Status" above before running this
|
|
systemctl enable --now oikos-console.service oikos-console-deploy.service
|
|
```
|
|
|
|
## Caddy route — done (2026-07-06), in `dtoro/caddy-conf`, not this repo
|
|
|
|
Live in `dtoro/caddy-conf` as of commit `c195142`, Authentik-gated
|
|
(confirmed syntax against the live Caddyfile: `import authentik`, no
|
|
parens in the import itself — the snippet is *defined* as `(authentik)`
|
|
but *imported* as `authentik`), same pattern as `paperless.hubris.network`:
|
|
|
|
```caddyfile
|
|
oikos.hubris.network {
|
|
import authentik
|
|
reverse_proxy 192.168.8.205:8091
|
|
}
|
|
```
|
|
|
|
Still needed: add `oikos.hubris.network` to the split-horizon DNS zone
|
|
(Technitium, LXC 107) pointing at Caddy's LAN IP, same as every other
|
|
`*.hubris.network` host — see the DNS section below.
|
|
|
|
## Authentik step-up re-auth on approval actions — deferred, needs live Authentik
|
|
|
|
The Week-4 plan calls for the `/approvals/{id}/reply` POST specifically
|
|
to require fresh re-authentication (not just an existing session), so a
|
|
stolen session cookie can't approve a mutation. That's an Authentik
|
|
policy binding (a `PromptStage`/reauth flow scoped to that path), which
|
|
needs a live Authentik instance to configure and test — not buildable or
|
|
verifiable from a repo checkout alone. Today the whole console (including
|
|
this route) is protected the same way every other console-with-a-forward-
|
|
auth-gate service is: the ingress-level Authentik check, not a per-action
|
|
step-up. Tracked in the 60/90-day backlog (OIKOS.md).
|
|
|
|
## What this deploy does NOT do
|
|
|
|
- Does not run any `homelab` command directly. Approving in the console
|
|
issues a grant token exactly like approving via Matrix would — actually
|
|
executing the gated action still goes through the `homelab` CLI on
|
|
whichever host runs it, with `--approval-id`.
|
|
- Does not touch inventory.yaml, secrets/, or anything outside
|
|
signals/ and approvals/ (both committed+pushed immediately on write,
|
|
see `oikos/console/app.py`'s `_commit_push()`).
|