id: cd48a4b0ae154eef886e4219e403a0a5
parent_id: e3e948d299184fd993f7269bd616138f
item_type: 1
item_id: 980c3eb587294e4383474b94988f2f88
item_updated_time: 1785659716780
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"tgreSQL \"],[-1,\"+ Redis \"],[0,\"(native \"]],\"start1\":893,\"start2\":893,\"length1\":24,\"length2\":16},{\"diffs\":[[0,\"kage\"],[-1,\"s or VirtualBox VM); backend\"],[1,\");\"],[0,\" `ca\"]],\"start1\":912,\"start2\":912,\"length1\":36,\"length2\":10},{\"diffs\":[[0,\"run`\"],[-1,\", frontend\"],[1,\" +\"],[0,\" Vit\"]],\"start1\":926,\"start2\":926,\"length1\":18,\"length2\":10},{\"diffs\":[[0,\"eBSD\"],[-1,\") | **Forgejo** (primary git host),\"],[1,\", LAN-only) |\"],[0,\" **J\"]],\"start1\":1020,\"start2\":1020,\"length1\":43,\"length2\":21},{\"diffs\":[[0,\" units (PG +\"],[-1,\" Redis +\"],[0,\" app binary \"]],\"start1\":1163,\"start2\":1163,\"length1\":32,\"length2\":24},{\"diffs\":[[0,\"ddy)\"],[-1,\", separate DB. Also\"],[1,\". Also file server +\"],[0,\" art\"]],\"start1\":1191,\"start2\":1191,\"length1\":27,\"length2\":28},{\"diffs\":[[0,\"act \"],[-1,\"+ backup \"],[0,\"stor\"]],\"start1\":1221,\"start2\":1221,\"length1\":17,\"length2\":8},{\"diffs\":[[0,\"*Produce\"],[1,\" / Git\"],[0,\"** | Het\"]],\"start1\":1237,\"start2\":1237,\"length1\":16,\"length2\":22},{\"diffs\":[[0,\"bian\"],[-1,\") | Public entry point. B\"],[1,\", public) | **Forgejo** (primary git host — public + private repos), b\"],[0,\"are \"]],\"start1\":1271,\"start2\":1271,\"length1\":33,\"length2\":78},{\"diffs\":[[0,\"ystemd**\"],[1,\" game\"],[0,\" service\"]],\"start1\":1352,\"start2\":1352,\"length1\":16,\"length2\":21},{\"diffs\":[[0,\"ices\"],[-1,\": PostgreSQL, Redis, Skara Brae\"],[1,\" (PG + app\"],[0,\" binary\"],[1,\")\"],[0,\", \"],[1,\"**\"],[0,\"Caddy\"],[1,\"**\"],[0,\" (TLS). \"],[-1,\"Jenkins deploys via SSH: copy binary → `systemctl restart skara-brae`. Hetzner also hosts a self-hosted **Codeberg** instance as git mirror/backup\"],[1,\"Planned **Codeberg** mirror for redundancy\"],[0,\". |\\\n\"]],\"start1\":1370,\"start2\":1370,\"length1\":207,\"length2\":87},{\"diffs\":[[0,\"orgejo (\"],[-1,\"basement\"],[1,\"Hetzner, internet SSH\"],[0,\") → Jenk\"]],\"start1\":1496,\"start2\":1496,\"length1\":24,\"length2\":37},{\"diffs\":[[0,\" Jenkins\"],[1,\" (basement)\"],[0,\" builds \"]],\"start1\":1528,\"start2\":1528,\"length1\":16,\"length2\":27},{\"diffs\":[[0,\"les \"],[-1,\"Linux binary\"],[1,\"via webhook\"],[0,\" → d\"]],\"start1\":1568,\"start2\":1568,\"length1\":20,\"length2\":19},{\"diffs\":[[0,\"en, \"],[-1,\"Jenkins SCPs the\"],[1,\"SCPs\"],[0,\" bin\"]],\"start1\":1626,\"start2\":1626,\"length1\":24,\"length2\":12},{\"diffs\":[[0,\"\\\n\\\n**\"],[-1,\"Sizing caveat:** the Hetzner box is \\\"decent, not a powerhouse\\\" and will also run Codeberg. A Rust text MMORPG binary is very light, but watch combined RAM (Codeberg + PG + Redis + app). Set a threshold for upsizing or splitting.\\\n\\\n**Why a Debian bhyve guest for staging (not a FreeBSD jail):** production is Debian. Running staging in a matching Debian VM\"],[1,\"Redis — deferrable for MVP.** Redis provides caching, leaderboards (sorted sets), and WebSocket pub/sub. At low player counts, the Rust process can hold session/leaderboard data in memory. Add Redis to prod when you need multi-process scaling or persistence across restarts. PostgreSQL handles all persistent data regardless. The schema and\"],[0,\" c\"],[1,\"r\"],[0,\"at\"],[-1,\"ches kernel/glibc/runtime surprises. Use FreeBSD jails only for FreeBSD-native services (file server, Jenkins, Forgejo, backups).\\\n\\\n**No Docker.** All services run as native systemd units (Linux) or jails (FreeBSD). No container overhead, simpler debugging, direct access to the binary\"],[1,\"e deps are ready; just swap the in-memory adapter for the Redis one when the time comes.\\\n\\\n**Sizing caveat:** the Hetzner box is \\\"decent, not a powerhouse\\\" and now also runs Forgejo (+ planned Codeberg mirror). A Rust binary + Forgejo is light, but watch combined RAM (Forgejo + Codeberg + PG + app). Set a threshold for upsizing or splitting\"],[0,\".\\\n\\\n-\"]],\"start1\":1680,\"start2\":1680,\"length1\":650,\"length2\":694},{\"diffs\":[[0,\"```\\\n\"],[-1,\"jan@basement\"],[1,\"git@hetzner\"],[0,\"/ska\"]],\"start1\":2532,\"start2\":2532,\"length1\":20,\"length2\":19},{\"diffs\":[[0,\"zner/skara-brae/\"],[1,\" \"],[0,\"        # Forgej\"]],\"start1\":2543,\"start2\":2543,\"length1\":32,\"length2\":33},{\"diffs\":[[0,\"jo o\"],[-1,\"rg or user repos\"],[1,\"n Hetzner (public + private)\"],[0,\"\\\n├──\"]],\"start1\":2575,\"start2\":2575,\"length1\":24,\"length2\":36},{\"diffs\":[[0,\"the \"],[-1,\"basement server. Hetzner mirrors via a self-hosted Codeberg instance\"],[1,\"Hetzner box (public-facing). Jenkins on the basement box connects via deploy key + webhook\"],[0,\". Se\"]],\"start1\":2866,\"start2\":2866,\"length1\":76,\"length2\":98},{\"diffs\":[[0,\".service\"],[-1,\" redis.service\"],[0,\"\\\nWants=p\"]],\"start1\":11897,\"start2\":11897,\"length1\":30,\"length2\":16},{\"diffs\":[[0,\"vice\"],[-1,\" redis.service\"],[0,\"\\\n\\\n[S\"]],\"start1\":11926,\"start2\":11926,\"length1\":22,\"length2\":8},{\"diffs\":[[0,\"0.1:6379\"],[1,\"          # only when Redis is deployed\"],[0,\"\\\nLISTEN_\"]],\"start1\":12291,\"start2\":12291,\"length1\":16,\"length2\":55},{\"diffs\":[[0,\"LS)\\\n```\\\n\"],[1,\"git.yourdomain.tld {\\\n    reverse_proxy 127.0.0.1:3000\\\n}\\\n\\\n\"],[0,\"api.skar\"]],\"start1\":12433,\"start2\":12433,\"length1\":16,\"length2\":73},{\"diffs\":[[0,\"e layout\"],[1,\", services glossary\"],[0,\"\\\n- [Game\"]],\"start1\":24305,\"start2\":24305,\"length1\":16,\"length2\":35}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-08-02T08:39:55.062Z
created_time: 2026-08-02T08:39:55.062Z
is_locked: 0
type_: 13