chore: harden docker-compose deployment (bind, memory limits, no-new-privileges)

- frontend publishes on ${FRONTEND_PUBLISH_ADDR:-127.0.0.1} not 0.0.0.0 (M4).
- mem_limit on backend(4g)/postgres(1g)/frontend(512m), .env-overridable (M3).
- security_opt: no-new-privileges on app + postgres services.
New knobs documented + allowlisted in the config meta-test; compose validates.
Deferred (need host verification): image pinning, backend healthcheck, cap_drop
on postgres/tor, Postgres backup sidecar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-07-13 22:10:29 +02:00
parent e6aefaa804
commit 70a6598924
3 changed files with 41 additions and 1 deletions

View File

@@ -23,6 +23,12 @@ services:
# takes the whole stack offline. Match the policy already set on
# tor / docker-socket-proxy / vision-manager.
restart: unless-stopped
# Bound Postgres so a runaway query/backlog can't consume all host RAM.
# Tune to your host via .env (should comfortably exceed shared_buffers +
# work_mem * max_connections).
mem_limit: ${POSTGRES_MEM_LIMIT:-1g}
security_opt:
- no-new-privileges:true
tor:
# SOCKS5 proxy for the crawler, plus a control port so the backend
@@ -197,6 +203,13 @@ services:
expose:
- "8080"
restart: unless-stopped
# Bound the heaviest consumer: the backend hosts the OCR/analysis worker and
# drives a headless Chromium crawler, either of which can balloon and
# OOM-kill the host (taking Postgres with it) with no limit. Tune to your
# host via .env — this default is a generous ceiling, not a target.
mem_limit: ${BACKEND_MEM_LIMIT:-4g}
security_opt:
- no-new-privileges:true
frontend:
build: ./frontend
@@ -213,8 +226,17 @@ services:
# to 300000 (5 min) in hooks.server.ts; raise/lower via .env.
BACKEND_PROXY_TIMEOUT_MS: ${BACKEND_PROXY_TIMEOUT_MS:-300000}
ports:
- "3000:3000"
# Bind to loopback by default so SvelteKit (plain HTTP; COOKIE_SECURE=true
# expects TLS in front) is reachable ONLY by a host-local reverse proxy,
# not cleartext over the LAN/internet. A host-external TLS terminator can
# set FRONTEND_PUBLISH_ADDR=0.0.0.0 (or a specific interface) in .env.
- "${FRONTEND_PUBLISH_ADDR:-127.0.0.1}:3000:3000"
restart: unless-stopped
# Cap runaway memory (SvelteKit is light, but bound it anyway) and forbid
# privilege escalation. Tune the limit to your host via .env.
mem_limit: ${FRONTEND_MEM_LIMIT:-512m}
security_opt:
- no-new-privileges:true
# ----- Vision autoscaling (profile: ai) -----------------------------------
# Two extra containers that idle-stop the mangalord-vision (llama.cpp)