Commit Graph
30 Commits
Author SHA1 Message Date
Frank 105a4cdfef deploy.sh: accept hermes-webui in the top-level service inventory 2026-08-26 08:22:23 -07:00
Frank d52bcc15f8 Migrate Gitea proxy to canonical Caddy 2026-08-25 21:56:04 -07:00
Frank bc718f04f4 Fix scoped deployment state and config ownership 2026-08-25 20:24:47 -07:00
Frank 1ba47e4d22 Deploy services independently by changed paths 2026-08-25 20:13:33 -07:00
Frank 835996a67b Keep deployment moving when Caddy restart is blocked 2026-08-25 16:55:10 -07:00
Frank eae5bc2565 Continue LLM deployment when compose restart fails 2026-08-25 16:54:18 -07:00
Frank c7a72b465e Fix privileged shared config deployment 2026-08-25 16:53:13 -07:00
Frank 3cc99d81cc Authentik SSO + homepage naked domain
Auth layer (Authentik 2026.8.0):
- compose: 3-service stack (authentik-postgres, authentik-server, authentik-worker),
  postgres health-gated, bind mounts under /home/dank/authentik
- Caddyfile: auth.franksdank.cloud vhost; forward_auth on the no-auth vhosts
  (homepage, SearXNG, Hermes, Prometheus, RomM, Copyparty); outpost path
  proxied first in a route block
- .env.example: AUTHENTIK_PG_PASS + AUTHENTIK_SECRET_KEY
- deploy.sh: render only CADDY_BASICAUTH_HASH (the homepage per-user hashes
  are retired; grafana + pihole keep basicauth)
- tests/authentik.bats (new) + updated homepage/caddyfile/pihole seams
- docs: Authentik.md + per-service pages; Caddy.md + Homepage.md updated

Homepage (naked domain):
- Caddyfile: dankclaw.franksdank.cloud -> franksdank.cloud www.franksdank.cloud;
  dankclaw + dankserver redirect to it; bare-IP catch-all updated
- addn-hosts: A records for the naked domain, www, and auth (all -> 143)
- tests/pihole.bats: vhost_names handles multi-address blocks; TLD check
  allows the naked domain

All 146 tests pass.
2026-08-24 23:48:27 -07:00
Frank c58dab0a89 Homepage: give the user page its own login (dankuser)
The homepage user page + shared data now use a dedicated CADDY_HOMEPAGE_HASH
(username dankuser), separate from the shared family password (CADDY_BASICAUTH_HASH,
username dank, still used by the other vhosts) and the operator password
(CADDY_ADMIN_HASH, username frank, the /admin/ page). This lets the homepage be
re-logged independently without touching the other sites. deploy.sh renders the
new placeholder; the .env.example documents all three hashes.
2026-08-23 21:08:21 -07:00
Frank b485a27784 deploy: run the /srv/homepage steps under sudo
The homepage deploy's mkdir/cp/write of /srv/homepage ran as the deploy user
and hit 'Permission denied' (/srv is root-owned). Prefix them with the sudo
wrapper, write deployed.js via a temp file + sudo cp, and chmod the tree
a+rX so Caddy can serve it. Run the one-off checker as root too (it writes
status.json into /srv/homepage).
2026-08-23 15:44:46 -07:00
Frank f400be76c6 deploy: make the Caddy hash grep defensive under set -e
A missing CADDY_*_HASH in the .env made the 'grep | tail | cut' pipeline
return non-zero, which aborted the deploy under 'set -e' before it could warn
and keep the placeholder. Add '|| true' so an absent hash warns instead of
aborting. (The homepage deploy aborted here because CADDY_ADMIN_HASH was not
in the repo-root .env the deploy reads.)
2026-08-23 15:25:53 -07:00
Frank 2e6c44f3ba Homepage (TDD slice 6): the git-driven deploy
Red tests first.
- tests/homepage_deploy.bats: the deploy ships the homepage (assets to
  /srv/homepage, the checker timer, both Caddy hashes, deployed.js) and is
  git-driven (pulls main); the checker runs as a systemd timer.
- scripts/homepage-status.service / .timer: the checker as a oneshot service
  + a 3-minute timer (Q2/Q35).
- scripts/deploy.sh: the Caddyfile render now substitutes BOTH hashes
  (REPLACE_WITH_HASH <- CADDY_BASICAUTH_HASH, REPLACE_WITH_ADMIN_HASH <-
  CADDY_ADMIN_HASH). A new homepage step copies the assets to /srv/homepage,
  generates deployed.js from the deployed commit's datetime (Q43), installs
  the checker timer, and runs the checker once so status.json exists at once.
- tests/llm_units.bats: scoped the three LLM-unit tests to
  frank-default-*.service (the homepage unit is a different pattern: it
  installs to /usr/local/bin and runs from /srv at deploy time).
2026-08-23 12:59:56 -07:00
Frank 6a9edd4ee0 deploy.sh: keep the relink comment free of a literal loop-var token
The explanatory comment contained an unescaped loop-variable token, which
the local shell (set -u) tried to expand while building the double-quoted
remote script ('unit: unbound variable'). Reword the comment.
2026-08-22 22:36:04 -07:00
Frank 33438f223e deploy.sh: fix LLM unit relink (unquote source path so ${unit} expands on the remote)
The relink loop wrapped the source path in single quotes, which shipped a
literal ${unit} to the remote and created a dangling symlink
(/etc/systemd/system/frank-default-large.service -> .../${unit}.service),
so 'systemctl enable' failed with 'unit does not exist'. The path has no
spaces; unquoting lets ${unit} expand on the remote for both source and
destination.
2026-08-22 22:33:16 -07:00
Frank fbfbc5c6db Move frank-default-large from :52625 to :7770 (dankclaw)
Operator request (2026-08-22): the primary inference server
(frank-default-large, the 27B CIRU model on Dankclaw) moves to the
standard llama.cpp port 7770. Both LLM services now listen on :7770,
distinguished by host (dankserver vs dankclaw).

Functional changes:
- scripts/frank-default-large.env: LISTEN_PORT 52625 -> 7770
- scripts/serve-frank-large.sh: default LISTEN_PORT 52625 -> 7770
- scripts/deploy.sh: LLM_HEALTH[dankclaw] -> :7770
- open-webui quadlet: OPENAI_API_BASE_URL -> 192.168.0.143:7770
  (re-pointed so chat keeps working; data dir preserved)
- scripts/bench-fast-greedy.sh: PORT 52625 -> 7770

Tests updated to the new topology (both LLM endpoints on :7770 by host;
open-webui -> :7770). Docs + pi KB updated; dated historical runbooks
keep their point-in-time ports. models.json (pi client) re-pointed to
:7770 separately, effective on the next client restart.
2026-08-22 22:11:53 -07:00
Frank 0461988884 scripts: unified deploy.sh; units + bench point at the merged checkout
deploy.sh now deploys both workloads per target in one run:
push -> pull on /home/dank/serverAppConfigs -> podman stack steps
(dankclaw) -> LLM unit relink + daemon-reload + service restart ->
homepage health + LLM health (up to 20 min model-load wait).
Sudo: plain sudo on the fleet hosts (passwordless verified
2026-08-22); FRANK_SUDO_PW covers headless runs elsewhere. The
vllmScripts deploy.sh is superseded.

Units: frank-default-{small,large,npu}.service now reference
/home/dank/serverAppConfigs/scripts/... (the merged checkout).
bench-spec-stack.sh: env file path updated to the merged checkout.
2026-08-22 15:50:39 -07:00
Frank 0951fc165c deploy.sh: restart caddy when the reload cannot be applied
A 'caddy reload' delivered over the admin API cannot apply a config
that disables the admin API -- the fix cannot ride the API it is meant
to enable (2026-08-22: admin off sat in the running config across
deploys). Track the reload result; on failure, restart the container
so it reads the rendered file on start.
2026-08-22 13:35:31 -07:00
Frank bb1ef9bfb3 caddy: keep admin on for hot reload; deploy.sh reloads after render
The Caddyfile had 'admin off', which disables Caddy's config file
watcher. Rendered Caddyfile changes never loaded until the container
was recreated, so the double-hash basicauth fix sat on disk unapplied
across deploys (2026-08-22). Admin binds to 127.0.0.1:2019 inside the
container and the port is unpublished, so nothing outside reaches it.

deploy.sh now issues an explicit 'caddy reload' (retry loop) after
'up -d', with the file watcher as backstop.
2026-08-22 13:22:01 -07:00
Frank 5c9ade4e7a deploy.sh: fix quoting of the cfhash label template 2026-08-22 04:16:18 -07:00
Frank e0a25415a1 deploy.sh: rebuild local images when their Containerfile hash changes
buildah can serve a stale COPY --from layer (cache keyed on stage
name), so a Containerfile edit silently produced an unchanged image.
The image now carries a cfhash label; a mismatch forces a --no-cache
rebuild.
2026-08-22 04:14:43 -07:00
Frank dc421efea4 deploy.sh: escape the image-build loop vars for the remote string 2026-08-22 04:04:24 -07:00
Frank 1f4766f233 observability: fix alloy ui component, busybox healthchecks for loki/alloy
- alloy 1.x renamed the server component to ui; the old block failed the
  initial load and the container crash-looped
- grafana/loki is distroless and grafana/alloy lacks wget, so their
  healthchecks could never run; local images add a static busybox from
  alpine for that one command
- deploy.sh builds all three local images if missing
- tests: 3 new seams
2026-08-22 03:59:14 -07:00
Frank d5e9c63802 deploy.sh: drop --pull=missing (podman-compose rejects it) 2026-08-22 02:51:36 -07:00
Frank 5caa2178c3 deploy.sh: extract CADDY_BASICAUTH_HASH via grep/cut, not by sourcing .env
Sourcing the .env in a set -u shell dies on the bcrypt hash's $2
expansion. grep/cut pulls the value without any shell interpretation.
2026-08-22 02:51:13 -07:00
Frank 7f4ce06927 Caddy phase 2: TLS via Porkbun DNS-01 wildcard certs
- Caddyfile: drop http:// site prefixes, global acme_dns porkbun block,
  HTTPS redirects on the bare-IP and legacy vhosts
- new dankclaw/caddy/Containerfile: xcaddy build with caddy-dns/porkbun
- compose: caddy uses franksdank/caddy-porkbun:latest + Porkbun env vars
- deploy.sh: build the image on first deploy if missing
- .env.example: rename PORKBUN_API_SECRET -> PORKBUN_API_SECRET_KEY
  (the name the caddy-dns/porkbun module expects)
- tests: 7 new caddyfile/compose seams for the TLS config
2026-08-22 02:39:41 -07:00
Frank e9277fa8af deploy.sh: declare the per-target arrays (COMPOSE_UP, COPY_SHARED) 2026-08-21 23:17:04 -07:00
Frank 6ea490d64c deploy: sed delimiter '|' for the Caddyfile hash render (bcrypt contains '/')
Plus a regression seam that reproduces the render with a slash-bearing
hash.
2026-08-21 21:48:15 -07:00
Frank 4a679fce80 Caddy consolidation: single Caddy on dankclaw fronts both hosts
Per user direction, Caddy runs only on dankclaw. It fronts every
service on both hosts: local services by container name, quadlet
services by published LAN port, dankserver services by published LAN
port (192.168.0.235:PORT).

- dankclaw/Caddyfile: merged vhost list (was: two Caddyfiles, one per
  host). gitea's single vhost moves in from the retired gitea-caddy
  quadlet (option B). Upstreams fixed to live reality: gitea :3000,
  search :8081 (gluetun), chat :3005 (open-webui quadlet), media
  services via 192.168.0.235. Retired: llms (open-webui on dankserver
  is removed; chat is its successor), the dankserver homepage (302 to
  the shared one).
- dankserver/Caddyfile, dankclaw/gitea/Caddyfile: deleted (git rm).
- dnsmasq addn-hosts: every name -> 192.168.0.143 (the one Caddy
  host); no .235 records, no llms.
- compose.yaml: removed the openwebui/postgres/gitea services (they
  are quadlets now); caddy service mounts the rendered Caddyfile from
  /home/dank/Containers/caddy, healthcheck probes the bare-IP
  catch-all (302).
- deploy.sh: per-target logic (dankserver = pull-only, health via the
  shared Caddy at 192.168.0.143); renders CADDY_BASICAUTH_HASH from
  the host .env into the mounted Caddyfile.
- .env.example: CADDY_BASICAUTH_HASH on dankclaw; Porkbun block
  dropped from dankserver (its Caddy is gone); SEARXNG_BASE_URL to
  the flat name; stale OPENAI_* block dropped (quadlet is
  self-contained).
- tests: caddyfile.bats now asserts the single-Caddyfile invariant;
  dnsmasq.bats cross-checks vhosts -> .143 and the retired names.
2026-08-21 21:44:18 -07:00
Frank e3cd2aca1b SearXNG: add limiter.toml trusted group (LAN /24), wire into deploy
The trusted group lives in limiter.toml, not settings.yml. Add
shared/searxng/limiter.toml trusting 192.168.0.0/24 in pass_ip and
trusted_proxies, copy it into /opt/searxng/config on deploy, and correct
the SearXNG doc. New test seam: tests/searxng_limiter.bats.
2026-08-18 13:55:37 -07:00
Frank e3eb5334cb feat: initialize serverAppConfigs with podman stacks for Dankserver and Dankclaw
- Dankserver stack: RomM, Copyparty, Calibre-Web, node-exporter
- Dankclaw stack: Gluetun VPN (SearXNG tunnel), SearXNG+Valkey, ComfyUI
  (CPU backend), OpenWebUI, Hermes, Gitea+Postgres (migrated), Caddy
  reverse proxy, Grafana+Prometheus+Loki+Alloy observability
- Caddyfiles with .local hostname convention and basicauth homepage
- bind-mount storage policy, no named volumes
- deploy.sh mirroring vllmScripts git workflow (push -> pull -> restart -> health)
- docs/ Obsidian vault: per-service docs from frank-default-small research
  subagents (promtail EOL -> Alloy; gitea SECRET_KEY preservation; ComfyUI --cpu)
- bats test suite at 6 seams — 22 tests green
2026-08-13 20:19:41 -07:00