83 lines
2.8 KiB
YAML
83 lines
2.8 KiB
YAML
|
|
# 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/<somewhere>/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://<unraid-ip>:8443/sse — MCP for AI clients
|
||
|
|
# https://<unraid-ip>:8443/ingest/... — transcript uploads from hooks
|
||
|
|
# https://<unraid-ip>: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
|