62 lines
2.0 KiB
Caddyfile
62 lines
2.0 KiB
Caddyfile
# MemPalace Caddy reverse-proxy config.
|
|
# -----------------------------------------------------------------------------
|
|
# Listens on :8443 with a self-signed (Caddy-internal) cert. Enforces a
|
|
# bearer-token check on every request and proxies authenticated traffic to
|
|
# the mempalace container.
|
|
#
|
|
# Two upstream paths:
|
|
# /sse, /messages* -> mempalace:8765 (mcp-proxy SSE for MCP tool calls)
|
|
# /ingest* -> mempalace:8766 (in-process HTTP ingest endpoint)
|
|
# /healthz -> mempalace:8766 (no auth, for liveness probes)
|
|
#
|
|
# Token comes from the MEMPAL_TOKEN env var (set in deploy/unraid/.env).
|
|
# -----------------------------------------------------------------------------
|
|
{
|
|
# Disable the admin API — never expose it from a container that's
|
|
# reachable from clients.
|
|
admin off
|
|
# Ship access logs to stderr so `docker logs caddy` is useful.
|
|
log {
|
|
output stderr
|
|
format console
|
|
}
|
|
}
|
|
|
|
:8443 {
|
|
tls internal
|
|
|
|
# Liveness probe — no auth so Docker / external monitors can hit it
|
|
# without holding the bearer token.
|
|
handle /healthz {
|
|
reverse_proxy mempalace:8766
|
|
}
|
|
|
|
# Auth gate. matcher passes only when the Authorization header is
|
|
# exactly `Bearer ${MEMPAL_TOKEN}`. Header matching is exact-match.
|
|
@authorized header Authorization "Bearer {$MEMPAL_TOKEN}"
|
|
|
|
# MCP-over-SSE: the MCP transport sends events on /sse and accepts
|
|
# JSON-RPC POSTs on /messages (path varies by mcp-proxy version, so
|
|
# proxy the whole prefix tree).
|
|
handle @authorized {
|
|
# SSE responses are streamed — disable buffering and force HTTP/1.1
|
|
# upstream to keep the event stream open.
|
|
reverse_proxy /sse* /messages* mempalace:8765 {
|
|
flush_interval -1
|
|
transport http {
|
|
versions 1.1
|
|
}
|
|
}
|
|
reverse_proxy /ingest* mempalace:8766
|
|
}
|
|
|
|
# Default: anything not matched above (or unauthenticated traffic) is
|
|
# rejected. Returning 401 instead of 403 is correct here — clients with
|
|
# no/invalid token can re-attempt with credentials.
|
|
respond 401 {
|
|
body "Unauthorized"
|
|
close
|
|
}
|
|
}
|