mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-18 08:56:41 +00:00
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.
57 lines
1.6 KiB
YAML
57 lines
1.6 KiB
YAML
# Monitoring stack for SuperSync Server
|
|
#
|
|
# Attaches to the external `super-sync-server_internal` network created by
|
|
# the base docker-compose.yml — the base stack must be brought up first
|
|
# (or merged into the same `up` invocation as below). Running this file
|
|
# standalone will fail with "network not found".
|
|
#
|
|
# Usage:
|
|
# docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d
|
|
#
|
|
# Access via SSH tunnel (from local machine):
|
|
# ssh -L 8080:localhost:8080 -L 3001:localhost:3001 yourserver
|
|
#
|
|
# Then open:
|
|
# - Dozzle (logs): http://localhost:8080
|
|
# - Uptime Kuma (uptime): http://localhost:3001
|
|
|
|
services:
|
|
# Real-time log viewer (~40MB RAM)
|
|
# Read-only Docker socket access for viewing container logs
|
|
dozzle:
|
|
image: amir20/dozzle:latest
|
|
container_name: dozzle
|
|
restart: unless-stopped
|
|
ports:
|
|
- '127.0.0.1:8080:8080'
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
environment:
|
|
- DOZZLE_NO_ANALYTICS=true
|
|
networks:
|
|
- internal
|
|
mem_limit: 64m
|
|
|
|
# Uptime monitoring + alerts (~120MB RAM)
|
|
# Provides health check monitoring and notifications
|
|
uptime-kuma:
|
|
image: louislam/uptime-kuma:1
|
|
container_name: uptime-kuma
|
|
restart: unless-stopped
|
|
ports:
|
|
- '127.0.0.1:3001:3001'
|
|
volumes:
|
|
- uptime-kuma-data:/app/data
|
|
networks:
|
|
- internal
|
|
mem_limit: 192m
|
|
|
|
# Attach to the internal network defined in docker-compose.yml so Kuma can
|
|
# probe http://supersync:1900/health by service name (not just public URL).
|
|
networks:
|
|
internal:
|
|
external: true
|
|
name: super-sync-server_internal
|
|
|
|
volumes:
|
|
uptime-kuma-data:
|