# Maven — Docker deployment One image, one container per daemon (`docker-compose.yml`). Core (`mavend`) holds the encryption key and the db; the modules mount only the shared socket dir and read-only models. ## First run ```sh # 1. generate the at-rest db key (32 bytes, base64) — keep it safe, losing it loses the db cp deploy/db_key.env.example deploy/db_key.env printf 'MAVEN_DB_KEY=%s\n' "$(openssl rand 32 | base64 -w0)" > deploy/db_key.env # 2. build + start docker compose build docker compose up -d # 3. logs docker compose logs -f mavend ``` `models/` and `deps/` are bind-mounted / baked from the host — they are NOT in git (fetched via `make deps` + downloaded models). The build context needs `deps/lib`, `deps/piper`, `deps/include`, and `deps/whisper.cpp/ggml/include` present (see `.dockerignore`). ## Layout | Path (in container) | What | |----------------------------|-----------------------------------------| | `/opt/maven/bin` | the six daemons | | `/opt/maven/lib` | native .so (whisper+vulkan, onnxruntime)| | `/opt/maven/piper` | piper binary + espeak data | | `/opt/maven/models` (ro) | bind-mount of `./models` | | `/run/maven` (volume) | shared IPC sockets | | `/var/lib/maven` (volume) | encrypted db at rest | | `/dev/shm` (tmpfs) | decrypted db working copy (RAM only) | ## Not yet verified / host-dependent This stack is correct-by-construction but has **not been build-tested here** (no docker in the authoring env; ~1GB context; GPU). Expect a tweak on first build on the target host, most likely in one of these: - **GPU passthrough** — `mavsttd` maps `/dev/dri` for Vulkan. On an NVIDIA host you'd swap to the nvidia container runtime instead of `/dev/dri`. - **onnxruntime lib path** — `mavend`'s embedder needs `libonnxruntime.so` (on `LD_LIBRARY_PATH=/opt/maven/lib`). If the embedder wants an explicit path, set it in the config's embedder block. - **cross-container voice** — `mavweb -voice mavend:9100` only works once `mavend` binds its voice server on `0.0.0.0:9100` (Voice config, currently unset). Until then, voice-over-web is inert; `/tools`, passkey, and the dash work fine over the core socket. - **netdata** — `mavpoll` reaches it via `host.docker.internal`; adjust if netdata runs elsewhere.