FJ-69: move the MCP state volume to /data and adopt the Nushell key recipe #89
Loading…
Reference in a new issue
No description provided.
Delete branch "chore/doc-formatting"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Moves the MCP HTTP service's state volume out of the application directory and swaps every key-generation recipe to Nushell. Docs-and-config plus two error strings; no decoding or control-flow behavior changes.
State volume:
/app/data->/data/appholds the binary andWORKDIR, so the SQLite state store was mutable state nested inside the immutable application directory. It now lives at/data:oci-build/Dockerfilecreates it, declaresVOLUME ["/data"], defaultsFORGEJO_MCP_DATABASE_URLbeneath it, and chowns it explicitly (chown -R appuser:appuser /app /data) because it no longer inherits ownership by sitting under/app.compose.mcp.ymlmountsforgejo-mcp-datathere, and.env.exampleplusdocs/deployment.mdagree.Verified by rebuilding the runtime image and running it:
/datais owned by uid 1001,FORGEJO_MCP_DATABASE_URL=sqlite:///data/forgejo-mcp.db, and a write probe asappusersucceeds.Compatibility: the volume name is unchanged and the database file sits at the volume root, so a default deployment resolves
/data/forgejo-mcp.dbto the same file it previously reached at/app/data/forgejo-mcp.db. An.envpinning the old absolute path must be updated, or the service writes to the container's writable layer and loses state on recreate.Key recipe:
openssl rand -base64 32->random binary 32 | encode base64Both emit the 44-character padded standard-base64 string the decoders require (
random binary 32 | encode base64 | str length->44on Nushell 0.112.2), but the Nushell form needs no external binary. Ten sites acrossREADME.md,docs/deployment.md,.env.example,compose.mcp.yml, and the two fail-closed startup errors incrates/fj-mcp/src/http.rs. Containing fences are retaggednu, and the pipeline is single-quoted inside compose's${VAR:?...}messages so the|cannot read as message punctuation;docker compose configrenders it correctly.The same OpenSSL recipe in the upstream
mcp-webcrate is out of scope here and is tracked in MCPWEB-9.Docs
docs/deployment.mdis reflowed to ~120 columns with aligned tables.Checks
just pre-commitgreen: fmt, clippy-D warnings, build, and the full suite (76 tests across the four crates plus doctests).#FJ-69
The runtime image kept its SQLite state under /app/data, nesting mutable state inside the immutable application directory that holds the binary and WORKDIR. It now lives at /data: the Dockerfile creates it, declares VOLUME ["/data"], chowns it explicitly (it no longer inherits ownership from /app), and defaults FORGEJO_MCP_DATABASE_URL beneath it; compose.mcp.yml mounts forgejo-mcp-data there. The volume name is unchanged and the database file sits at the volume root, so a default deployment resolves to the same file; only an .env pinning the old absolute path needs updating. Every key-generation recipe is now the Nushell `random binary 32 | encode base64` instead of `openssl rand -base64 32`. Both emit the 44-character padded standard-base64 string the decoders require, but the Nushell form needs no external binary. This covers README.md, docs/deployment.md, .env.example, compose.mcp.yml, and the two fail-closed startup errors in crates/fj-mcp/src/http.rs; the containing fences are retagged nu, and the pipeline is quoted inside compose's ${VAR:?...} messages so the pipe cannot read as punctuation. docs/deployment.md is reflowed to ~120 columns with aligned tables. The same OpenSSL recipe in the upstream mcp-web crate is tracked in MCPWEB-9 and is out of scope here. #FJ-69