Services & Resource Optimization
Services List
| Service | Subdomain | Image | RAM Limit | Profile | Purpose |
|---|---|---|---|---|---|
| Proxy | traefik.h5h.me | Traefik v3 | 256 MB | core | Reverse proxy + auto TLS |
| SSO | auth.h5h.me | Authentik | 800 MB | core | Login, 2FA, Google sign-in, OIDC |
| SSO Worker | (internal) | Authentik | 512 MB | core | Background tasks |
| SSO DB | (internal) | Postgres 16 Alpine | 256 MB | core | Authentik database |
| SSO Cache | (internal) | Redis 7 Alpine | 64 MB | core | Authentik Redis |
| Dashboard | sh.h5h.me | Homepage | 128 MB | core | Service dashboard + widgets |
| Tunnel | — | cloudflared | 128 MB | core | Zero-trust tunnel |
| Photos | photos.h5h.me | Immich | 512 MB | photos | Google Photos replacement |
| Photos ML | (internal) | Immich ML | 1.5 GB | photos | Face/object recognition |
| Photos DB | (internal) | Postgres 14 + pgvectors | 512 MB | photos | Immich database |
| Photos Cache | (internal) | Valkey 8 Alpine | 128 MB | photos | Immich Redis |
| Drive | drive.h5h.me | Nextcloud | 512 MB | drive | Google Drive replacement |
| Drive DB | (internal) | Postgres 16 Alpine | 512 MB | drive | Nextcloud database |
| Drive Cache | (internal) | Redis 7 Alpine | 64 MB | drive | Nextcloud Redis |
| Notes | notes.h5h.me | Obsidian (Web UI + Git) | 1 GB | drive | Browser-based Obsidian |
| Media | plex.h5h.me | Plex | 512 MB | plex | Movies, TV, music |
| Torrents | torrent.h5h.me | qBittorrent + VueTorrent | 256 MB | plex | Seedr-like torrent → Plex pipeline |
| Monitoring | grafana.h5h.me | Grafana OSS | 192 MB | monitoring | Dashboards + security panel |
| Metrics | prometheus.h5h.me | Prometheus | 256 MB | monitoring | Time-series DB (15d retention) |
| Host Metrics | — | Node Exporter | 64 MB | monitoring | OS-level metrics |
| VPN | — | Tailscale | 128 MB | vpn | Mesh VPN + subnet router |
| IDS | — | CrowdSec | 256 MB | security | Intrusion detection |
| IDS Bouncer | — | CrowdSec Bouncer | 64 MB | security | Blocks bad IPs at proxy |
| Logs | — | Loki 3.4.3 | 256 MB | security | Log aggregation (30d) |
| Log Shipper | — | Promtail 3.4.3 | 64 MB | security | Ships logs to Loki |
| Backup | — | docker-volume-backup | 256 MB | backup | Nightly data backups (7d) |
26 services, ~8.0 GB total
8 GB RAM optimization
Every container has a mem_limit + critical services have memswap_limit (prevents swap thrashing). Default 26 containers total ~8.0 GB — you cannot run everything at once on 8 GB.
Recommended profiles
| Profile | Command | RAM Used | What you get |
|---|---|---|---|
| Minimal | make core | ~2.1 GB | Dashboard + SSO + Proxy + Tunnel |
| + Photos | make photos | ~4.3 GB | + Immich (server + ML + DB + Redis) |
| + Drive | make drive | ~5.4 GB | + Nextcloud (app + DB + Redis) + Obsidian |
| + Media | make plex | ~5.9 GB | + Plex + qBittorrent |
| + Monitoring | make monitoring | ~6.4 GB | + Grafana + Prometheus + Node Exporter |
| + Security | make security && make vpn | ~7.1 GB | + CrowdSec + Loki + Tailscale |
Stay under ~6 GB to leave headroom for OrbStack VM (~500 MB) and macOS (~1.5 GB).
Key optimizations
| Optimization | What it does |
|---|---|
Postgres shared_buffers=128MB | Prevents Postgres from hogging RAM |
Immich ML MODEL_TTL=300 | Unloads ML models after 5 min idle |
| CrowdSec bouncer first | Drops malicious packets early (Latency savings) |
| Log rotation (10 MB × 3 files) | Caps log disk usage |
memswap_limit = mem_limit | Prevents swap thrashing on Postgres instances |
OrbStack setup (recommended for M1 Mac)
brew install --cask orbstackOrbStack uses ~50% less RAM than Docker Desktop and has faster VirtioFS I/O (faster Immich thumbnails, Nextcloud indexing).
Docker base OS
On MacBook Air M1, Docker Desktop runs a lightweight Alpine Linux VM (arm64) as the host. All container base images have native arm64 support — no Rosetta emulation needed.
External dependencies worth knowing
- Obsidian (
notes.h5h.me) — on first boot only, the container usesDOCKER_MODS=linuxserver/mods:universal-git+ theobsidian/init.shhook to clonehttps://github.com/callmehetch/notes-obsidianinto/config. If the vault volume is wiped or this repo disappears, the first start will begin empty. See external_dependencies.md. - Immich machine-learning — the ML container downloads models on demand.
MACHINE_LEARNING_MODEL_TTL=300unloads them after 5 minutes idle; a cold search therefore re-pulls the model intoimmich-model-cache.
Image pinning
Most services run :latest. See upgrade_runbook.md for the policy (which images are hard-pinned, which are rolling, how to bump safely).
Single source of truth
This doc explains why the services look the way they do. The what (one row per service, subdomain, image, RAM, profile, SSO tier) is maintained in service_catalog.md and regenerated from docker-compose.yml + docker/scripts/setup_rbac.py by make gen-docs.