# Shared MemPalace server (optional) — one palace for many clients. # # Runs `mempalace-mcp` over HTTP so several containers/harnesses (pi + # opencode + native) can share ONE palace instead of each keeping its own. # Point every client at it by setting, in that client's .env: # # MEMPALACE_REMOTE_URL=http://:8765/mcp # # (see .env.example). When set, the client connects over HTTP and does NOT # spawn its own local mempalace-mcp. # # Start: docker compose -f docker-compose.mempalace.yml up -d # Stop: docker compose -f docker-compose.mempalace.yml down # Logs: docker compose -f docker-compose.mempalace.yml logs -f # # Why reuse the devbox image? mempalace-mcp is already installed in it, and # reusing it GUARANTEES the server's mempalace version matches the clients' # (both are pinned by the same image build). Override with a slimmer image via # MEMPALACE_SERVER_IMAGE if you prefer (it must provide `mempalace-mcp`). # # ⚠ SECURITY: mempalace-mcp's HTTP transport has NO authentication of its own. # Do NOT expose port 8765 to an untrusted network. The default below binds to # 127.0.0.1 (host loopback) only. To let sibling containers reach it, either # attach them to the shared `mempalace-net` network (container-to-container, no # host port needed — use http://mempalace-server:8765/mcp), or front it with a # reverse proxy that enforces MEMPALACE_REMOTE_TOKEN as `Authorization: Bearer`. name: mempalace-server services: mempalace: image: ${MEMPALACE_SERVER_IMAGE:-joakimp/pi-devbox:latest} container_name: mempalace-server # Bypass the devbox entrypoint (dev-shell/LAN/config setup) and run the # HTTP MCP server directly. HOME + explicit --palace pin the data path so # it does not depend on the image's default user/HOME. Runs as root so it # can initialise the fresh named volume; the volume is dedicated to this # server (clients reach it over HTTP, never by mounting it). entrypoint: [] user: "0:0" environment: - HOME=/data command: - mempalace-mcp - --transport - http - --host - "0.0.0.0" - --port - "8765" - --palace - /data/.mempalace restart: unless-stopped # Loopback-only by default (see SECURITY note). Use "8765:8765" to expose on # all host interfaces, or drop `ports:` entirely and rely on mempalace-net. ports: - "127.0.0.1:8765:8765" volumes: # The shared palace data — precious; back this up. - mempalace-shared:/data/.mempalace # Embedding-model cache (~79 MB, disposable) so search does not re-download. - mempalace-shared-chroma:/data/.cache/chroma networks: - mempalace-net healthcheck: # A tools/list round-trip proves the server is answering MCP (python3 is # always present — mempalace itself is a python tool in the image). test: - CMD - python3 - -c - "import urllib.request,json; d=json.dumps({'jsonrpc':'2.0','id':1,'method':'tools/list','params':{}}).encode(); r=urllib.request.Request('http://127.0.0.1:8765/mcp',data=d,headers={'Content-Type':'application/json','Accept':'application/json'}); urllib.request.urlopen(r,timeout=5).read()" interval: 30s timeout: 10s retries: 3 start_period: 60s volumes: mempalace-shared: mempalace-shared-chroma: networks: mempalace-net: name: mempalace-net