Comment-only follow-up to the docker-compose healthcheck fix: the Caddyfile note still said localhost:2019; align it to the literal IP the probe now uses.
Right-size container limits to fit a 4GB / 2-vCore VPS host without
OOM risk, and apply minimal best-practice hardening informed by
multi-agent review.
Container memory budget (sum 2816 MB, leaves ~1.2 GB host headroom):
- postgres: 1g → 1.5g (was at 74% under 199 WSS connections)
- supersync: 1g → 768m (uses 143 MiB steady state)
- dozzle: add 64m cap (was unbounded)
- uptime-kuma: add 192m cap (was unbounded)
- caddy: unchanged at 256m
Postgres tuning (1.5g cap, shm_size 256m to allow shared_buffers > 64m):
- shared_buffers=384MB, effective_cache_size=1GB
- work_mem=4MB, maintenance_work_mem=128MB
- max_connections=40 (Prisma pool is single-digit; 40 leaves headroom
for migrations + psql; 100 was an OOM landmine vs 1.5g cap)
- random_page_cost=1.1 (SSD)
- idle_in_transaction_session_timeout=300000 (5 min — catches leaked
Prisma idle-in-tx but stays well above migrate-deploy.sh
STEP_TIMEOUT=1800 for CONCURRENTLY index recovery)
- wal_compression=on, huge_pages=off
Other hardening:
- Standardize restart policy to unless-stopped across all services
- Add caddy healthcheck via admin API at localhost:2019; Caddyfile
comment warns future edits not to disable admin
- Add ulimits.nofile=65535 to supersync (Alpine soft default 1024 is
tight for 200+ WSS + reconnect bursts)
- Pin networks.internal.name=super-sync-server_internal so the
monitoring overlay can attach via external: true regardless of
COMPOSE_PROJECT_NAME
- Attach dozzle + uptime-kuma to internal network so Kuma can probe
http://supersync:1900/health by service name
Notes for future maintenance:
- oom_score_adj was tried and removed: Compose v2 silently ignores it
(verified on host via /proc/<pid>/oom_score_adj returning 0).
Would need a systemd post-up hack to apply — not worth it.
- The reconnect storm that motivated this work is fixed separately
on master in b404bf8a3.
Caddy v2 reverse_proxy does not support a top-level `timeout`
subdirective. The response_header_timeout in the transport block
already covers long-running operations.