T-HUB/docs/ops/2026-10-12-cloud-hosting-requirements.md

5.2 KiB
Raw Permalink Blame History

Cloud hosting requirements — occupymedia.cc stack

Date: 2026-10-12 Basis: measured on the production home deployment (CT 150 app, CT 152 chat, CT 320 files) — see the table for real numbers, not estimates.

What runs where

Everything except object storage and the CF edge is self-hostable on ONE VPS:

  • Hub app: api, scheduler, web (Next.js), intake site, Element Web client
  • Data: Postgres, Redis, Temporal, chat homeserver (tuwunel/RocksDB), files server (oCIS S3NG + optional Collabora)
  • Edge: cloudflared tunnel, nginx edge, certbot, failover watchdogs
  • Media worker (transcoding): can stay OFF the box (distributed worker model — e.g. the planned Windows/NVENC node joins over tailscale)

Externalized by design (never self-host): R2 object storage (all media payloads — files, chat media, video), Cloudflare (DNS, ingress, failover), Telegram/Matrix federation peers.

Measured footprint (production, today)

Component RAM used Disk used Notes
App CT (everything above) 1.0 GB / 16 GB 147 GB* *images + build artifacts + snapshots — real data is small
Chat CT (tuwunel + RocksDB) 145 MB / 4 GB 7.8 GB grows slowly: new media → R2
Files CT (oCIS + Collabora) 1.4 GB / 8 GB 13 GB metadata only; payloads in R2
R2 (object storage) — 385 GB on account** **occupymedia usage ≈ 0 today; the 385 GB is another project sharing the account

Real concurrent RAM: ~2.6 GB total. Media payloads are externalized to R2, so disk does NOT grow with video/uploads.

Sizing

Tier Specs What it covers Ref. price (Hetzner-class)
Minimum 4 vCPU / 8 GB RAM / 160 GB SSD full stack at current usage ~€15/mo
Comfortable 8 vCPU / 16 GB RAM / 240 GB SSD + live-event spikes, on-box transcoding, Collabora sessions ~€30/mo
  • CPU: 4 vCPU is enough if video transcoding stays distributed (render workers join over tailscale — the design). On-box transcoding wants 8.
  • RAM: 8 GB floor (Temporal + oCIS + Postgres headroom); 16 GB makes live events boring.
  • Disk: does not grow with media (R2 externalized). 80–160 GB lasts years.
  • Bandwidth: near-zero egress (R2/Cloudflare deliver media; R2 has zero egress fees).
  • Object storage (R2): pay-per-GB (~$0.015/GB/mo) + small ops fees. Current occupymedia usage ≈ 0; expect low single-digit $/mo at collective scale.

Single-box placement

One VPS runs the consolidated stack (all three home CTs on one host):

  • Docker compose projects: occ-app, occ-chat, occ-files, occ-edge, occ-element, occ-intake — the same compose files in infra/occupymedia/.
  • Ingress: Cloudflare tunnel (remotely managed — config lives in the CF dashboard, re-point at the new box) + the edge nginx + watchdogs (the ipfs3 relay failover works from any location; from a cloud box it is redundant but harmless).
  • Tailscale optional on a cloud box (its address is already public).

Migration runbook (home → cloud)

Ordered; each step reversible:

  1. Prereq: fresh VPS (Ubuntu 24.04), Docker + compose plugin, tailscale (optional), DNS ready (CF API token).
  2. Data export (from home, per store):
    • Postgres: pg_dump (owner format) → transfer.
    • Chat: stop tuwunel → tar occ-chat_conduwuit_data volume (final snapshot exists; make a fresh one) → transfer. Keep tuwunel.toml (has R2 creds).
    • Files: stop oCIS → tar ocis-config + ocis-metadata volumes → transfer. (Blobs are in R2 — they do not move.)
    • Hub files folders: they are oCIS resources (in R2) — nothing extra.
  3. R2: unchanged — same account, same buckets, same keys. If the VPS region differs, no action (R2 is anycast).
  4. Restore on the VPS: start postgres → restore dump → restore chat/files volumes from tars → start stacks in order (datastores → api/scheduler/web → chat → files → edge) → apply any pending migrations with the api CLI.
  5. Ingress cutover: install cloudflared with the same tunnel token (the tunnel id moves with the token; ingress config is remote) → connections register from the new box. Re-point tunnel ingress service URLs from 192.168.13.x/100.x addresses to the VPS's local container names/ports.
  6. Edge + watchdogs: copy the edge dir; the ipfs3 relay and ingress watchdog keep working (the watchdog flips DNS to the relay if the new box's CF path is ever sick).
  7. Verify (the standard checklist): api/web/chat/files/element health, login, collective creation mints rooms, archive E2E (upload → R2 → bot → files), restore tooling round-trip.
  8. Rollback: home stack stays intact until step 7 passes; DNS flips back in one API call.

Cost picture

Item Monthly
VPS (comfortable tier) ~€30
R2 storage (grows with media) ~$1–5 at collective scale, zero egress
Cloudflare free tier $0
Total ~€30–35/mo all-in

What was measured vs assumed

Measured: RAM/disk per CT (table above), R2 bucket inventory + usage, docker image sizes, component list. Assumed: audience scale stays collective-sized (tens–hundreds of users); video delivery rides R2/CF (no self-hosted CDN egress); transcoding off-box. Re-measure after the first large live event.