Skip to content

infra: deploy co-located Mnemonic MCP server with webapp CORS - #1

Open
mnemonik-dev wants to merge 19 commits into
developfrom
claude/fabric-architecture-review-cqyj9m
Open

infra: deploy co-located Mnemonic MCP server with webapp CORS#1
mnemonik-dev wants to merge 19 commits into
developfrom
claude/fabric-architecture-review-cqyj9m

Conversation

@mnemonik-dev

@mnemonik-dev mnemonik-dev commented Jul 10, 2026

Copy link
Copy Markdown
Owner

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.

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
mnemonik-dev force-pushed the claude/fabric-architecture-review-cqyj9m branch from edb2bd2 to 9401e3c Compare July 12, 2026 10:02
@mnemonik-dev mnemonik-dev changed the title Claude/fabric architecture review cqyj9m infra: deploy co-located Mnemonic MCP server with webapp CORS Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant