Commit Graph
349 Commits
Author SHA1 Message Date
Bot 9316a32ba5 ai: persist FlowAgent MSAL token cache via mcpo bind mount
Adds the missing bind mount for FlowAgent's delegated-user MSAL disk
token cache:

    /volume1/docker/mcpo/flowagent-auth:/app/flowagent-auth

Confirmed via `docker service inspect ai_mcpo --format '{{json .Spec.TaskTemplate.ContainerSpec.Mounts}}'`-equivalent review of the current
compose that mcpo's mounts were only: ssh_keys, config.json, mcpo_data,
uv-cache -- flowagent-auth (set as HOME for the flowagent subprocess via
config.json.template's env.HOME=/app/flowagent-auth) was NOT persisted,
so any successful delegated-user MSAL sign-in (list_connections /
create_connection / resolve_refs / pick_or_create_connection /
resolve_params -- the tools that use MsalTokenProvider, see companion
homelab/mcp-config PR #9) would be silently lost on every mcpo restart,
forcing a fresh interactive sign-in every time.

Host dir already exists (pre-created on shared CephFS, identical across
all three docker LXCs):
    mkdir -p /volume1/docker/mcpo/flowagent-auth

This does NOT change the flowagent image tag/pin -- that stays
git.bryanmail.net/homelab/flowagent-mcpo:c5b22618404a pending the
companion mcp-config PR merging and its Woodpecker build producing a new
commit-sha tag to bump to.

No other changes to ai.yaml in this commit -- diff is mount-list addition
only.
2026-09-09 00:16:35 -07:00
AVB 5a5c8e56a9 Merge pull request 'Fix phantom verify failure: secrets/ is not a stack + errexit-proof verify' (#17) from fix-secrets-folder-stack-detection into main
ci/woodpecker/push/deploy Pipeline was successful
ci/woodpecker/cron/renovate Pipeline failed
Reviewed-on: #17
https://ai.bryanmail.net/c/9f4c84c7-7aa1-4b24-a27e-98be6a5e737e
2026-09-07 22:28:36 -07:00
Bot eee6e543b1 Fix phantom verify failure: exclude secrets/ from stack detection + errexit-proof verify's stack-ps
Root cause of PR #16's pipeline failure (#398-#401): secrets/ is a
tooling folder (secrets-map.yaml, *.secrets.example), not a stack, but
folder-detection (cut -d/ -f1, excluding only deploy/) computed
ALL_STACKS="ai secrets" the first time a commit touched secrets/. The
deploy step survived only because 'secrets' coincidentally sits in the
bootstrap-tier skip list; verify had no guard — `docker stack ps
secrets` exited non-zero and, under errexit, the OUTPUT=$(...)
assignment killed the step before the designed WARNING path could run.
The ai deploy itself was fully successful (complete 21-key render, all
6 services healthy) — the failure was pure phantom. Hazard first
flagged July 2026 in PR #3 (closed unmerged).

Changes:
- grep -v '^deploy$'  ->  grep -vE '^(deploy|secrets)$' in ALL five
  folder-detection sites (validate, provision-secrets x2, deploy,
  verify)
- verify: `|| true` inside the stack-ps command substitution so a
  genuinely missing stack warns instead of aborting (comment added)
- deploy step: also rsync secrets/ tooling to the host mirror
  unconditionally, same treatment as deploy/
- header: 2026-09-08 incident note

Everything else byte-identical to main. Dollar-escape audit done.
2026-09-07 22:26:43 -07:00
AVB be587de5be Merge pull request 'Provisioning v2 (take 2): data-only manifest + full-file env template + generic provisioner — replaces #15' (#16) from secrets-provisioning-v3 into main
ci/woodpecker/push/deploy Pipeline failed
Reviewed-on: #16
https://ai.bryanmail.net/c/9f4c84c7-7aa1-4b24-a27e-98be6a5e737e
2026-09-07 22:06:03 -07:00
Bot ef7e3d015e provision-secrets: ai) case -> provision-stack.py + normalized env block (branch rebuilt on current main)
Same two scoped changes as PR #15's rebase, now applied on a branch cut
from TODAY's main so the merge base is current (PR #15 became
unmergeable — its 09-03 merge base predated main's heavy hand-edits):

1. ai) case -> `python3 deploy/provision-stack.py ai` (one line). Retires
   main's heredoc with its live drift: AI_LITELLM_POSTGRES_PASSWORD
   printed twice (one copy from retired AI_LITELLM_DB_PASSWORD), stray
   legacy AI_WEBUI_SECRET_KEY, and the WEB_UI/WEBUI shell-var mismatch
   that renders an EMPTY OAuth client secret into ai.env.
2. env block ai section: normalized to exact template placeholder names,
   added AI_MCPO_API_KEY (NEW Woodpecker secret required pre-merge),
   pruned now-template-literal vars.

apk gains python3 py3-yaml. Everything else byte-matches current main.
Dollar-escape audit done per header lesson.
2026-09-07 21:47:04 -07:00
Bot 89a1e030c0 Add deploy/provision-stack.py — generic manifest-driven provisioner
Carried over from secrets-provisioning-v2 (PR #15), content identical.
Whole-file template render (hard-fail naming missing vars), env + Docker
secrets shipped via ssh stdin only, sha256-checksum skip-if-unchanged,
never prints a value. Stacks absent from the manifest exit 0 so legacy
case-entries keep handling them.
2026-09-07 21:43:57 -07:00
Bot e82b754386 Add ai/ai.env.template — full-file authoritative env template (AI_<SERVICE>_* naming)
Carried over from secrets-provisioning-v2 (PR #15) post-rebase. Key names
match exactly what current ai/ai.yaml references; MCPO_API_KEY stays
unprefixed (ai.yaml consumes it unprefixed for both mcpo services).
Placeholder names match the CI env vars declared in deploy.yml's
provision-secrets block, including the normalized
AI_OPEN_WEBUI_OAUTH_CLIENT_SECRET (fixing main's WEB_UI/WEBUI mismatch
that currently renders an EMPTY OAuth client secret into ai.env).
NEW Woodpecker secret required before merge: ai_mcpo_api_key.
2026-09-07 21:43:05 -07:00
Bot 85734f4601 Add secrets/secrets-map.yaml — data-only provisioning manifest (ai stack first)
Carried over from secrets-provisioning-v2 (PR #15), which became
unmergeable after heavy parallel hand-edits to main moved the merge base
too far. Content identical to v2.
2026-09-07 21:43:04 -07:00
AVB 264f4e7379 Change AWS_REGION_NAME variable
ci/woodpecker/push/deploy Pipeline was successful
ci/woodpecker/cron/renovate Pipeline was successful
2026-09-06 20:33:56 -07:00
AVB 9bbbd5fae3 Add AWS Region Name variable
ci/woodpecker/push/deploy Pipeline was successful
2026-09-06 20:33:08 -07:00
AVB e33fd8695f Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline was successful
ci/woodpecker/cron/renovate Pipeline was successful
2026-09-06 10:59:05 -07:00
AVB 1828c89194 Update .woodpecker/deploy.yml
ci/woodpecker/push/deploy Pipeline was successful
2026-09-06 10:53:55 -07:00
AVB 9ec5353d7e Fixed LITELLM Database URL
ci/woodpecker/push/deploy Pipeline was successful
2026-09-06 10:44:53 -07:00
AVB dfa0d34a83 Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline was successful
2026-09-06 10:29:27 -07:00
AVB 66638dd743 Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline was successful
2026-09-06 01:29:02 -07:00
Bot 355ccada8c Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline failed
ci/woodpecker/cron/renovate Pipeline was successful
2026-09-03 00:15:38 -07:00
Bot 096ebd6de5 Update .woodpecker/deploy.yml
ci/woodpecker/push/deploy Pipeline was successful
2026-09-02 23:28:25 -07:00
Bot 980c54f84e Update .woodpecker/deploy.yml 2026-09-02 23:27:19 -07:00
Bot 324a06ed2d Update .woodpecker/deploy.yml 2026-09-02 23:26:30 -07:00
Bot cee47822ec Update .woodpecker/deploy.yml 2026-09-02 23:25:39 -07:00
Bot 68365746a6 Update .woodpecker/deploy.yml 2026-09-02 23:24:37 -07:00
Bot eecfcf9367 Update .woodpecker/deploy.yml 2026-09-02 23:23:57 -07:00
Bot d01c763354 Update .woodpecker/deploy.yml
Redeploy after adding secret:
secret "ai_open_web_ui_openid_provider_url" not found
2026-09-02 23:17:48 -07:00
Bot 0baee47b67 Fixed duplicate env: "AI_OPEN_WEB_UI_ENABLE_OAUTH_SIG"
yaml: construct errors: line 190: mapping key "AI_OPEN_WEB_UI_ENABLE_OAUTH_SIGNUP" already defined at line 186
2026-09-02 23:02:51 -07:00
Bot 0435def8a0 Update .woodpecker/deploy.yml
Added Open WebUI and LiteLLM secrets
2026-09-02 23:01:44 -07:00
Bot ded255decc Upgrade to open-webui:0.11.3
ci/woodpecker/push/deploy Pipeline was successful
open-webui:0.11.1 > open-webui:0.11.3
2026-09-02 22:26:15 -07:00
Bot ac091999b4 Merge pull request 'FlowAgent MCP cutover: point ai.yaml's mcpo at flowagent-mcpo image + wire Azure secrets (matched pair)' (#14) from flowagent-ai-cutover into main
ci/woodpecker/push/deploy Pipeline failed
Reviewed-on: #14
https://ai.bryanmail.net/c/9f4c84c7-7aa1-4b24-a27e-98be6a5e737e
2026-09-02 21:43:18 -07:00
Bot a15e0100df provision-secrets: add flowagent_* case-entry to the ai) stack (matched pair with ai.yaml's mcpo cutover)
Surgical addition to the existing case "ai)" block only — every other
case, comment, and line in this ~26KB pipeline file is byte-for-byte
unchanged from main. Given this file's documented incident history from
prior full-file rewrites (see header comment), this was hand-verified
against the current main content line-by-line before writing, not
generated fresh.

Adds:
  - 3 new environment: entries (FLOWAGENT_AZURE_CLIENT_ID/TENANT_ID/
    CLIENT_SECRET) via from_secret, alongside the existing ai_* secrets
  - Inside the existing `ai)` case, after the ai.env rewrite block: three
    create_or_update_secret calls provisioning flowagent_azure_client_id,
    flowagent_azure_tenant_id, flowagent_azure_client_secret as native
    Docker Swarm secrets (Pattern C, _FILE convention) — NOT written into
    ai/ai.env, since mcpo's flowagent entry reads them via
    /run/secrets/flowagent_azure_* per flowagent/entrypoint.sh, not env vars
  - A short comment explaining why these three are Pattern C secrets
    inside an otherwise Pattern-B (host .env) stack case

This is the matched-pair companion to the ai.yaml commit in this same PR,
per the FlowAgent progress note's explicit sequencing requirement (both
land together, reviewed, not auto-merged to main).
2026-09-02 16:53:10 -07:00
Bot bcfb24b16d ai.yaml: cut mcpo over to the confirmed-working flowagent-mcpo image + wire flowagent Docker secrets (never touches mcpo-critical)
Image pinned to git.bryanmail.net/homelab/flowagent-mcpo:916164714429 —
the exact sha-tagged image built and smoke-tested clean in mcp-config
pipeline #22 (build-and-push-flowagent + smoke-test-flowagent-image both
success). NOT :latest, for reproducible deploys.

Adds a secrets: block to the mcpo service only, referencing the 3
flowagent_azure_* Docker Swarm secrets (Pattern C, _FILE convention,
consumed by flowagent/entrypoint.sh via /run/secrets/flowagent_azure_*).
Declares those 3 secrets as external at top level, mirroring the existing
vaultwarden_admin_token_v2 pattern in vaultwarden.yaml.

Companion secret-provisioning change lands in the same PR as a separate
commit in .woodpecker/deploy.yml's provision-secrets step (case "ai)").

mcpo-critical (lines defining Proxmox access) is completely untouched —
still stock ghcr.io/open-webui/mcpo:main, no secrets: block, unchanged.

Per FlowAgent MCP progress note: Azure AD App Registration is reported
created with real secrets already in Woodpecker (both mcp-config and
compose-files repos) as of this PR. This is a reviewed PR against a
feature branch, NOT auto-merged to main — deploy only happens after
manual review/merge, per user's explicit request for a manual-revert
safety net on this high-blast-radius shared stack (LiteLLM, Open WebUI,
n8n also live here).
2026-09-02 16:51:31 -07:00
Bot 42d31e38e4 git stack: switch provision-secrets to Pattern B .env rewrite (test phase) + add git to bootstrap-tier guard
ci/woodpecker/push/deploy Pipeline was successful
ci/woodpecker/cron/renovate Pipeline was successful
Context: git hosts the source of truth for every other stack's compose
files, so in a disaster-recovery scenario it must be restorable from a
flat git.yaml + git.env backup alone, with zero dependency on a running
Swarm's Docker secret store (native Docker secrets can't be resolved
until Swarm already exists, which is the circular dependency git.yaml
would otherwise create). Path 2 (documented decision): Pattern B for
git specifically, same mechanism the ai stack already uses.

provision-secrets / git) case:
  - Previously created native Docker secrets (git_db_password,
    git_runner_token, git_mcp_access_token) via create-secrets.sh —
    leftover from an earlier, abandoned Pattern C attempt.
  - Now rewrites only the secret-bearing lines (GITEA__database__PASSWD,
    GITEA_RUNNER_REGISTRATION_TOKEN, GITEA_MCP_ACCESS_TOKEN) via
    grep -v + printf, mirroring the ai) case exactly. Also strips the
    legacy GITEA_ACCESS_TOKEN key name so the test file converges on the
    git.env.example-documented key.
  - TEST PHASE: target is git.env.pipelinetest, NOT git.env. The real
    git.env is never opened for writing by this step. First run seeds
    the test file from the real git.env (to carry over all non-secret
    lines), then only the 3 secret lines are refreshed on every push.
  - Real cutover (pointing git.yaml/stack-deploy at the generated file,
    then retiring git.env.pipelinetest) is a deliberate follow-up step
    after manually diffing the rendered output.

deploy / bootstrap-tier guard:
  - Added git to the traefik|woodpecker|postgresql|secrets guard list.
    git.yaml changes now sync to the host but require a manual
    `stack-deploy.sh git` run, same as the other foundational stacks —
    prevents an auto-deploy of a bad git.yaml change from taking down
    Gitea before a human can look at it (Gitea itself is what every
    other pipeline needs to trigger a fix).
2026-09-02 00:02:36 -07:00
AVB 16a01a9ea5 Merge pull request 'Remove orphaned mcpo/ mirror (migrated to homelab/mcp-config)' (#13) from remove-orphaned-mcpo-mirror into main
ci/woodpecker/push/deploy Pipeline failed
ci/woodpecker/cron/renovate Pipeline was successful
Reviewed-on: #13
2026-08-29 20:57:58 -07:00
admin b6b23a7970 Remove mcpo/woodpecker-mcp.mjs — migrated unchanged to homelab/mcp-config 2026-08-29 20:46:01 -07:00
admin 150b262db3 Remove orphaned mcpo/config.json mirror — migrated to homelab/mcp-config
This file was never actually deployed by this repo's pipeline (ai.yaml
bind-mounts /volume1/docker/mcpo/config.json on the host directly; nothing
here ever synced it there — see homelab/mcp-config README for full writeup).
It also contained several real plaintext credentials (Proxmox token,
Authentik JWT/token, UniFi password, Gitea tokens) that have since been
rotated and templated in the new repo.

NOTE: deleting this from HEAD does not remove it from compose-files' git
history. The rotated credentials must be treated as permanently compromised
regardless of this deletion.
2026-08-29 20:46:00 -07:00
admin 44babb6a22 Fix YAML alias-scanner crash: quote KEEPALIVED_PASSWORD/KEEPALIVED_VIRTUAL_IPS env values
ci/woodpecker/push/deploy Pipeline was successful
mount-guard.py failed with "expected alphabetic or numeric character, but
found '*'" during rendering. Root cause: KEEPALIVED_PASSWORD and
KEEPALIVED_VIRTUAL_IPS were interpolated unquoted; when the live secret
value happens to start with '*', YAML's scanner parses it as an alias
reference (*anchor) instead of literal text. KEEPALIVED_UNICAST_PEERS on
the adjacent line was already quoted for the same reason (starts with
'#') - this brings the other two env values in line with that existing
convention. Also noted (not fixed here): live traefik-certs-dumper
service is running v2.10.0 while this file already pins v2.11.4 -
redeploy needed separately to pick that up.
2026-08-29 14:03:36 -07:00
AVB 10c35138db Bump traefik-certs-dumper:v2.10.0 to 2.11.4
ci/woodpecker/push/deploy Pipeline was successful
2026-08-29 13:56:35 -07:00
admin 162700bb4f Fix: stack-deploy.sh now picks export_raw/export_raw_merged for folder+extras stacks (docker compose config path) vs export/export_merged for single-file stacks, matching envparse.py's dual-escaping fix
ci/woodpecker/push/deploy Pipeline was successful
ci/woodpecker/cron/renovate Pipeline was successful
2026-08-26 23:26:32 -07:00
admin 4af1209565 Fix: second double-interpolation bug in envparse.py - add export_raw/export_raw_merged (no escape_dollar) for the docker-compose-config render path, which already does its own dollar-escaping. Fixes IMMICH_KIOSK_BASICAUTH bcrypt hash corruption.
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 23:25:46 -07:00
admin a557d9fb07 Refactor: unify stack-deploy.sh render paths into a single temp-file render step, then run mount-guard.py before docker stack deploy
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 23:04:11 -07:00
admin f696efef11 Add: mount-guard.py - pre-deploy bind mount existence + Postgres empty-data heuristic check
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 23:03:11 -07:00
admin 2e889323ef Fix: correct immich.env-example paths to match real on-disk data (UPLOAD_LOCATION, BULK_UPLOAD_LOCATION, DB_DATA_LOCATION) after 2026-08-26 incident where generic template paths were wrong
ci/woodpecker/push/deploy Pipeline failed
2026-08-26 22:51:37 -07:00
admin b620682a41 Fix: envparse.py strip mode now also drops top-level 'name:' key that docker compose config emits but Swarm's stack deploy schema rejects
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 22:37:38 -07:00
admin 87a254c902 Fix: envparse.py strip mode now collapses long-form depends_on mapping to Swarm-compatible short-form list
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 22:35:53 -07:00
admin efd8caa218 Fix: invoke git-guard.sh via bash explicitly so tracked file mode bit doesn't matter
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 22:33:21 -07:00
admin 70814970c7 Harden .gitignore: broaden .env exclusion to *.env (with explicit exceptions for global.env and *.env-example templates), ignore stray .bak files
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 22:32:32 -07:00
admin 32e30f7e8b Add: call git-guard.sh at top of stack-deploy.sh to enforce sync before deploy
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 22:31:12 -07:00
admin 0bc117c868 Add: git-guard.sh - pre-deploy sync check to prevent local/Gitea divergence
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 22:30:47 -07:00
AVB 7b5273b4b4 Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 21:36:48 -07:00
AVB 9d0e9d9b60 Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 21:28:03 -07:00
AVB 08949ba3a4 Update ai/ai.yaml
ci/woodpecker/push/deploy Pipeline was successful
2026-08-26 21:24:17 -07:00
admin ef4bcfcb25 ai: trigger redeploy to apply $$ escaping fix (PR #8) to litellm secrets
ci/woodpecker/push/deploy Pipeline was successful
Comment-only change. Forces a real deploy of the ai stack now that
PR #8 (envparse.py $$ escaping) and PR #9 (deploy/ folder exclusion)
are both merged, so litellm picks up the correctly-escaped
LITELLM_MASTER_KEY/LITELLM_SALT_KEY instead of the truncated values
currently running (truncated at the first literal '$' due to the
envsubst+Compose double-interpolation bug fixed in #8).
2026-08-26 21:18:26 -07:00