Portfolio — the server as a project
DILMUN
one machine, everything on this site — and the discipline that keeps a single person able to run it
Dilmun is a home server run by one person for a family and a few friends. It is not a product and not a platform anyone else can sign up to. This page describes its architecture and the ideas behind it; it deliberately names no addresses, ports or components you could knock on.
What it is
A single dedicated machine in a data centre, running everything else you see on this site: the chat assistant, the games server, the monitoring demo, a Minecraft world, and the platform that decides who may open what. The interesting part is not the hardware. It is the set of rules that let one person keep all of that safe without a team — and the rule that everything about it is written down.
The architecture
-
01
The front door
One reverse proxy with two faces: public sites with strict headers, rate limits and a ban list; private sites drop any connection not arriving over the private mesh — before a byte of response.
-
02
Access tiers
Household models are untrusted by design: read tools plus a few enumerated verbs. The owner operates through attended sessions. Planning has no hands at all.
-
03
Eanna
The platform’s own login. Members sign in once on a private host; protected apps ask the front door, which asks Eanna, before a request reaches them.
-
04
Humbaba
A watcher with no open sockets. It reads logs and system events and messages the owner — immediately for what matters, once a day for the rest.
-
05
Kuma & the boot check
Uptime checks on every service, and after every reboot a script that prints a pass/fail table for the whole stack.
-
06
The round loop
Built in numbered rounds by a planner AI and an executor AI, the owner relaying between them and holding every credential.
The public internet sees exactly three doors — a web front door and the game’s own protocol — and everything else exists only on a private mesh network that members join with their own devices. There is no VPN gateway to attack, no admin panel on the open web, no SSH port in the world’s port scans. New services are born private; going public is a separate, recorded decision.
Enumerated writes. No component that a model can reach has a generic command path. Actions are fixed verbs with schemas, limits and audit lines, and adding a capability means adding one more verb — never widening an existing one.
Logs are data. Log lines, chat messages, tool results and web pages are treated as untrusted input by every automated reader — never as instructions. That one rule is what makes it safe to let an AI executor read the machine’s own logs.
Written canon. State, architecture, rules, decisions, traps and runbooks live as documents next to the code and are updated in the same session that changes anything. The machine can be rebuilt from the canon; the canon cannot be rebuilt from the machine.
Verify, don’t assume — and “proven” includes the negative test. A private site is not private until a public address has been shown to get nothing. A backup is not a backup until something has been restored from it. Nightly database dumps on the same disks are called what they are — a local copy, not a backup — until an off-site copy exists.
Feature highlights
-
Three public doors
Two web ports and the game protocol. Everything else is dropped at the network layer twice — by the host and by the hosting provider’s own firewall.
-
Private by default
New services start on the private mesh; going public is a separate, recorded decision.
-
One login for the private side
Eanna signs members in once; every protected app asks before it answers.
-
A watcher that tells the owner
Logins, new devices, bans, a private page answered to a public address — on the phone within seconds.
-
Pull-based deploys
Nothing pushes into the box. Timers pull from git, validate, restart, and write one log line per deploy.
-
Zero-touch reboot
A reboot ends with a pass/fail table for the whole stack — recovery is a tested property, not a hope.
-
Everything in slices
One project, one directory, one compose project — taking one down provably touches nothing else.
-
Honest backups
Local copies are labelled local copies; a restore drill precedes trusting any of them.
How it was built
Dilmun replaced a rented virtual server that had grown by accretion: a mail stack nobody used, a content system with one page, three login systems. The rebuild kept the ideas and the texts and started the software again with one rule per lesson learned — most of them learned the hard way on the old box.
Nothing was migrated. The games came back from their repository, the monitoring demo from its own, the site from the old one, and the platform was written new. What carried over was the canon: the written record of why things are the way they are.
Tech stack
- Ubuntu
- Docker Compose
- Caddy
- Tailscale
- PostgreSQL
- Python
- FastAPI
- systemd timers
- fail2ban
- Uptime Kuma
- Claude (planner/executor loop)
Closing note
Dilmun — one machine, one person, everything written down. No dashboards, no addresses, no numbers on this page — deliberately.