Files
Maven/docker-compose.yml
T
kami 04c8dd1406 deploy: dockerize — one image, one container per daemon
Compose stack replacing start-maven.sh's bare `&`-backgrounded processes.
Single multi-stage image builds all six daemons (CGO + prebuilt native libs
from deps/); compose runs one container each with a different command. Only
mavend mounts the encryption key (env_file, gitignored) and the db volume; the
modules mount just the shared unix-socket dir and read-only models — so the
"key-free modules" boundary is OS-enforced (separate namespaces), not just a
code convention. IPC stays unix-domain over a shared volume: zero code change,
paths move to /run/maven. Encrypted db at rest on a named volume, decrypted
working copy in tmpfs (RAM) per the at-rest encryption landed earlier.

Validated: `docker compose config` clean, mavend.json parses, all daemon flags
confirmed. NOT build-tested (no docker/GPU in authoring env) — deploy/README.md
lists the host-dependent tweak points (GPU passthrough, onnxruntime path,
cross-container voice bind, netdata host).

Chosen Docker over interim systemd units per the "dockerize soon" call — no
throwaway supervisor built.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 21:38:21 +04:00

74 lines
2.5 KiB
YAML

name: maven
# One image (built once), one container per daemon. Only mavend holds the key
# and the db volume; the modules mount just the shared socket dir + models.
# IPC stays unix-domain over the shared `sockets` volume — no code change from
# the bare-metal setup, only paths move to /run/maven.
x-image: &image
image: maven:latest
restart: unless-stopped
services:
mavend:
<<: *image
build: .
command: ["mavend", "-config", "/opt/maven/config/mavend.json"]
# the key lives ONLY here. deploy/db_key.env holds MAVEN_DB_KEY=<base64-32B>.
env_file: [./deploy/db_key.env]
volumes:
- dbdata:/var/lib/maven # encrypted db at rest
- sockets:/run/maven # IPC socket dir
- ./deploy/mavend.json:/opt/maven/config/mavend.json:ro
- ./models:/opt/maven/models:ro
# the decrypted working copy lives in RAM (see db_tmpfs in mavend.json).
tmpfs:
- /dev/shm
mavsttd:
<<: *image
command: ["mavsttd", "-socket", "/run/maven/stt.sock", "-model", "/opt/maven/models/stt/ggml-small.bin"]
depends_on: [mavend]
# whisper uses libggml-vulkan → needs the GPU render node.
devices:
- "/dev/dri:/dev/dri"
volumes:
- sockets:/run/maven
- ./models:/opt/maven/models:ro
mavttsd:
<<: *image
command: ["mavttsd", "-socket", "/run/maven/tts.sock",
"-piper", "/opt/maven/piper/piper",
"-model", "/opt/maven/models/tts/ru_RU-irina-medium.onnx",
"-espeak_data", "/opt/maven/piper/espeak-ng-data"]
depends_on: [mavend]
volumes:
- sockets:/run/maven
- ./models:/opt/maven/models:ro
mavweb:
<<: *image
# NOTE: -voice must reach mavend's voice TCP server cross-container. That
# requires mavend to BIND its voice server on 0.0.0.0:9100 (Voice config,
# currently unset). Until that's configured, voice-over-web is inert — the
# rest of mavweb (/tools, passkey, dash) works over the core socket.
command: ["mavweb", "-addr", ":9201", "-voice", "mavend:9100", "-core", "/run/maven/mavend.sock"]
depends_on: [mavend]
ports: ["9201:9201"]
volumes:
- sockets:/run/maven
mavpoll:
<<: *image
command: ["mavpoll", "-socket", "/run/maven/mavend.sock", "-netdata", "http://host.docker.internal:19999"]
depends_on: [mavend]
extra_hosts:
- "host.docker.internal:host-gateway" # reach netdata on the host
volumes:
- sockets:/run/maven
volumes:
dbdata:
sockets: