Deliverable #5 · 2026-08-02
lor-game-server-01 is live: server notes and how to deploy to it
The deliverable is a running machine, not a page — lor-game-server-01 at lor-server.cocreations.com.au (209.38.29.22), serving the director, the world processes, and the browser client. Deliverable
Deliverable #4 was the runbook: exact commands to go from “no droplet exists” to “a WebSocket connection reaches a running Godot process.” server-instance/001 executed it end-to-end, via the DigitalOcean API rather than by hand. This is that: what’s actually running, right now, and how to work with it.
The box
- Droplet:
lor-game-server-01, ID589446588, regionsyd1(Sydney), sizes-1vcpu-2gb(2 GB RAM / 1 vCPU / 50 GB SSD, ~US$12/month), imageubuntu-24-04-x64, taglor-game-server. - Address:
209.38.29.22— currently served plain HTTP, no domain yet: http://209.38.29.22/. - Access:
ssh lor@209.38.29.22with the dedicated runner SSH key. Root login and password auth are both disabled — key-only, non-root, matching deliverable #4 §2. - Provisioned via the DigitalOcean API against deliverable #4 as the spec, not through the console — see
server-instance/001’s dated notes for the exact deviations (cloud-init key injection instead of the droplet API’sssh_keysfield, a bundle-transferred git clone instead of droplet-side GitHub auth, and why).
What’s running, and how it’s arranged
- Hardening (deliverable #4 §2):
ufwactive, allowing only OpenSSH/80/443;fail2banandunattended-upgradesboth enabled. - Postgres (§4): a dedicated
lor_gamerole and database — not the superuser role — reachable only from127.0.0.1. Its password lives in an environment file on the box, never in git or a command line. - Godot (§3): 4.7.1 headless, x86_64, at
/usr/local/bin/godot4. - systemd (§6):
lor-director.serviceand the templatedlor-world@.service(currently one instance,lor-world@1), bothenabledandactive. The director’s own runtime (Node vs. Go) is still an open question inserver-architecture— its unit currently points at a placeholderExecStart. - Caddy (§5): reverse-proxying
/director/*and/world/N/*to the director and world processes on localhost. Running §5.2b, bare IP over plain HTTP — no domain is pointed at the box yet, so there’s no TLS. Fine for a small number of trusted testers at this stage; not something to point real players at. - The game code itself, and a temporary stand-in for it:
/opt/lor/game-serveris a real clone ofland-of-lor,originpointing athttps://github.com/krisrandall/land-of-lor.git. Butland-of-loris still docs/ideation stage — there’s no server-side Godot project in it yet — so a minimal stub (project.godot,main.gd,main.tscn: just enough for aWebSocketMultiplayerPeerlistener) was added directly on the droplet, deliberately not committed to git (excluded via.git/info/exclude). This is what made the systemd units and the end-to-end WebSocket check genuinely verifiable rather than just “the service exists.” It needs to be deleted once real server code lands — and if real files of the same names arrive viagit pullfirst, that pull will need manual reconciliation rather than a clean fast-forward.
Deploying code to it
The workflow is deliverable #4 §7 — a manual pull-and-restart, deliberately not a CI pipeline at this project’s current stage:
cd /opt/lor/game-server
git pull --ff-only
sudo systemctl restart lor-director.service
sudo systemctl restart 'lor-world@*.service'
If git pull --ff-only refuses, stop and reconcile by hand — never force, reset, or rebase automatically, same rule this workspace’s own deploy-watch.sh follows.
One thing stands between this and actually working today: the clone on the box was seeded by transferring an already-authenticated bundle over SFTP, not by giving the droplet its own GitHub credentials — deliberately, since handing a box real GitHub access wasn’t in scope for the provisioning task itself. Until a deploy key is added, git pull on the box has nothing to authenticate with. Follow-up: set up a deploy key scoped read-only to land-of-lor on the droplet before relying on this workflow for a real change.
Day-to-day ops (deliverable #4 §9)
- Is it up?
systemctl status lor-director lor-world@1 postgresql caddy, andcurl -I http://209.38.29.22should return200. - Logs:
journalctl -u lor-director -f,journalctl -u lor-world@1 -f,journalctl -u caddy -f,journalctl -u postgresql -f— everything logs to journald, no separate log files to hunt for. - Before anything risky (an OS upgrade, a schema migration, a systemd unit rewrite): take a DigitalOcean snapshot. Power off first (
sudo poweroff, then Droplet → Snapshots → Take Snapshot in the DO console) — a live snapshot of a running Postgres data directory isn’t guaranteed consistent. - Rough cost: ~US$12/month for the droplet itself; snapshots bill separately, roughly $0.06/GB/month — a few dollars a month at most for occasional snapshots of a box this size.
Open follow-ups
None of these block anything else in this epic or in server-architecture — recorded here so they’re not lost, not because anything is stuck:
- DO project assignment. The token used to provision lacked
project:read, so the droplet couldn’t be looked up or moved into alor-game-serverDO project via the API — it currently sits in DO’s Default project. A few seconds in the console, or grant the tokenproject:readfor a future session to do it via API. - Deploy key for
/opt/lor/game-server, as above — the thing that actually makes the §7 deploy workflow usable. - Domain and TLS. Once a domain is pointed at
209.38.29.22, switch the Caddyfile from §5.2b to §5.2a for automatic Let’s Encrypt TLS. - Billing alert. Recommended as part of provisioning (
server-instance/Q001step 5) but not independently verifiable by the provisioning session — nobillingscope, by design. Worth Kris confirming by hand in the DO console. - The stub Godot project described above needs replacing with real server code once
land-of-lorhas any, and the director’s runtime placeholder needs the real implementation onceserver-architecture’s one open question lands.
Sources & artifacts
epics/server-instance/tasks/001-provision-droplet-via-do-api.mdepics/server-instance/questions/001-droplet-provisioning-credentials.mddeliverables/004-server-setup-guide.md
← related epic: server-instance
Also available as raw markdown.