# MemPalace Unraid Compose # ----------------------------------------------------------------------------- # Two-container stack: mempalace (MCP-over-SSE on 8765 + HTTP ingest on 8766, # both bound to localhost only) plus a Caddy sidecar that terminates TLS, # enforces a bearer token, and reverse-proxies both endpoints on :8443. # # Use this with the Unraid Compose Manager plugin. Build context is the # repo root (../..); on Unraid, sync the repo to /mnt/user//mempalace # and from this directory run: # # # 1. Generate a token (do this once, keep it secret): # openssl rand -hex 32 > .env.token # echo "MEMPAL_TOKEN=$(cat .env.token)" > .env # rm .env.token # # # 2. Build and start: # docker compose up -d --build # # Endpoints (after start): # https://:8443/sse — MCP for AI clients # https://:8443/ingest/... — transcript uploads from hooks # https://:8443/healthz — liveness, no auth # # Caddy uses a self-signed cert (`tls internal`); clients must accept it, # typically via a `--insecure`-style flag or by trusting the Caddy root CA. # ----------------------------------------------------------------------------- services: mempalace: build: context: ../.. dockerfile: Dockerfile image: mempalace-server:latest container_name: mempalace restart: unless-stopped # Not published on the host — only Caddy reaches these ports over the # internal compose network. This is the auth boundary. expose: - "8765" - "8766" volumes: - /mnt/user/appdata/mempalace:/data environment: MEMPALACE_PALACE_PATH: /data/palace MEMPALACE_INGEST_PORT: "8766" MEMPALACE_INGEST_HOST: "0.0.0.0" # Defense-in-depth — Caddy is the primary gate, but if it's bypassed # (e.g. someone exec'd into the container's network), the ingest # server still requires the token. MEMPALACE_INGEST_TOKEN: "${MEMPAL_TOKEN}" # Languages for entity detection (comma-separated): # MEMPALACE_ENTITY_LANGUAGES: en user: "99:100" networks: - mempal # Override the image CMD: bind mcp-proxy to all interfaces inside the # container network so Caddy can reach it. The ingest server thread # spawns from MEMPALACE_INGEST_PORT. command: > mcp-proxy --sse-host 0.0.0.0 --sse-port 8765 --pass-environment -- mempalace-mcp caddy: image: caddy:2-alpine container_name: mempalace-caddy restart: unless-stopped depends_on: - mempalace ports: - "8443:8443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - /mnt/user/appdata/mempalace-caddy/data:/data - /mnt/user/appdata/mempalace-caddy/config:/config environment: MEMPAL_TOKEN: "${MEMPAL_TOKEN}" networks: - mempal networks: mempal: driver: bridge