infra: deploy co-located Mnemonic MCP server with webapp CORS - #1
Open
mnemonik-dev wants to merge 19 commits into
Open
infra: deploy co-located Mnemonic MCP server with webapp CORS#1mnemonik-dev wants to merge 19 commits into
mnemonik-dev wants to merge 19 commits into
Conversation
Deploys the SERVER side of the Mnemonic protocol (Rust MCP image from GHCR + local Ollama) co-located on the fabric VM, fronted by the shared Caddy instead of the monorepo's own nginx/certbot. Distinct from the client-binary mnemonic-mcp role. - role: compose (mcp + ollama, nginx/certbot dropped), state bind-mounted on the persistent volume, GHCR pull, ollama model pull, Caddy vhost, health gate - deploy.yml: gated behind mnemonik_server_enabled (default false), secrets threaded from sops (vault_mnemonik_mcp_jwt_secret / _refresh_salt) - secrets template: documents the two hosted-mode secrets - 8 contract tests, ansible-lint at sibling baseline, playbook syntax-check ok
The synchronous ollama model pull held the SSH run until the deploy was killed (run 29000156212), aborting before the Caddy reload + health gate. Make it async/poll:0/failed_when:false (model not needed for MCP core; pulls lazily for /chat). Add docker ps + mnemonik-mcp-1 log capture on health failure since the CI runner can't be SSH'd post-run.
Probing the public hostname from the VM hairpins to its own public IP and hangs, stalling the SSH run until the CI job is cancelled (~15 min) with unreadable logs. Probe Caddy via --resolve :127.0.0.1 with -m 5 hard timeout, fast-fail (40x3s). Always dump docker ps + mnemonik-mcp-1 logs + a direct docker-exec /health so the 502 root cause is visible in the CI log.
…tart
The mcp image pre-creates /data/model-cache + /data/rag_chunks and downloads
its fastembed ONNX model there on first boot. Bind-mounting the empty host
/data masked those dirs, so fastembed couldn't write the model and the server
FATALed ('No embedding provider available') in a restart loop -> Caddy 502
(run 29005805686 logs). Pre-create the subdirs (0777) on the host bind.
…d can start Debug probe (run 29010408334) proved: container runs as uid 10001/gid 999, HF egress works (hf=200), but /data (bind-mounted, owned by op/1000 mode 0700) was 'Permission denied' to the container -> fastembed couldn't access its cache -> FATAL restart loop -> 502. chown -R the persistent-volume /data + /keypair to 10001:999. Widen health gate to ~6min for first-boot model download + RAG seed. Remove the one-shot debug probe.
…ats env, embedding provider check - Add optional mnemonik_mcp_cors_origin; Caddy emits preflight + simple CORS headers for the browser webapp at https://mnemonik.xyz. - Set FASTEMBED_CACHE_DIR so the embedding model download persists on the Hetzner volume across VM rebuilds. - Add CHAIN_STATS_WALLETS / SOLANA_RPC_URL env vars required by server images >= #194. - Verify fastembed initialized from container logs after deploy. - Fix role contract tests for CORS disabled-by-default check.
- mnemonik_mcp_cors_origin can now be a string or a list. - Caddy reflects the request Origin when it matches an allowed origin. - Update group_vars to allow www.mnemonik.xyz and mnemonik-webapp.pages.dev.
Caddy's `header` matcher only accepts a single value, so the multi-origin render broke the shared Caddy config and left port 443 unbound. Switch to an expression matcher that ORs the allowed origins. Also capture Caddy logs + listening sockets in MCP diagnostics so a similar failure is obvious in CI.
A prior failed mnemonik-server deploy left a broken Caddy snippet in the shared conf.d. vaultwarden starts Caddy before mnemonik-server runs, so the invalid snippet caused Caddy to crash-loop and the whole deploy to fail before mnemonik-server could rewrite it. Delete the stale snippet as a pre-task; mnemonik-server will render the fixed one later.
mnemonik-dev
force-pushed
the
claude/fabric-architecture-review-cqyj9m
branch
from
July 12, 2026 10:02
edb2bd2 to
9401e3c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the mnemonik-server Ansible role, enables it in group_vars, and wires CORS for the Cloudflare-hosted webapp origins (https://www.mnemonik.xyz and https://mnemonik-webapp.pages.dev). Also includes the stale-Caddy-snippet recovery fix needed after the previous failed deploy.