This is how Albgott is actually built.
Not a tidied-up architecture diagram — the real hardware, network, and services, three years of ad-hoc growth included. Where it's uneven, it stays uneven here.
Getting online
The internet enters through hardware I don't fully control. The ISP's own router terminates the WAN handoff and, by contract, can't be removed from the chain — so there are, a little absurdly, two routers stacked on top of each other before traffic reaches anything I actually manage: the ISP's box first, then mine.
Mine is a MikroTik hEX S — a router/firewall with no Wi-Fi radio at all, chosen deliberately as a routing appliance and nothing else. There's a small, honest story behind why it has no Wi-Fi: it wasn't entirely a plan. I ordered it without checking that it shipped Wi-Fi-less, missed the return window, and only afterward realized the accident had actually reinforced something worth keeping anyway — routing and firewalling shouldn't also be a Wi-Fi access point. So home wireless is served by a separate, older router from a previous ISP, kept around purely to be the Wi-Fi bridge into the network. Three boxes doing the work that in a datacenter would be one piece of gear, each there for a slightly different reason — contractual, deliberate, and accidental.
From the MikroTik, a managed switch fans out over trunk ports to every machine on the network — five of them, each carrying whatever VLANs it needs. What those machines are, and why their hardware doesn't match each other at all, is the next section.
The machines
Nothing here was specced out in advance, and none of it was bought for the role it ended up playing. The cluster grew entirely out of hardware that was already sitting around — a repurposed laptop, a decommissioned office desktop, a tower with more headroom than the other two combined — and roles got assigned to what already existed, not the other way around. That history is visible in the specs below, and I'd rather show it than smooth it over.
Three Proxmox nodes carry almost everything:
| Node | Hardware | RAM / Disk | What it carries |
|---|---|---|---|
| pve01 | Repurposed laptop (Asus GL502VS) | 32 GB · 500 GB SSD + 1 TB HDD | Ingress and day-to-day dev tooling |
| pve02 | Decommissioned office desktop (Dell OptiPlex 7050) | 16 GB · 256 GB | Observability stack |
| pve03 | Dell T160 tower | 64 GB · 8 TB single disk | Data and the public-facing critical services |
The sizing isn't symmetric, and that's on purpose even if the hardware itself wasn't chosen on purpose: pve02 runs metrics and dashboards, which is I/O-heavy but not RAM-hungry, so it got the smallest machine. pve03 holds actual state — databases, object storage, public traffic — so it got, by a wide margin, the most RAM and the most disk of the three. The laptop follows the same logic from the other end: nothing that needs real performance or holds anything that matters runs on pve01, precisely because the T160 exists for that instead — and because a laptop is not hardware anyone should trust with anything that matters: no ECC memory, no redundant power, a battery and hinges never built to run 24/7, and cooling designed for a desk, not a rack.
Machine names quietly follow Norse mythology (odin, brokkr, eitri, thor) — a bit of personality that costs nothing to keep — but the names actually used day-to-day, in configs, monitoring, and conversation, are the boring operational ones (pve01, pve02, pve03, dns01). That's deliberate: a name needs to be quick to say and instantly understood by anyone on the inside, and "pve03" does that in a way "thor" never will.
Out-of-band management is uneven too: only pve03 has a real hardware console reachable independently of its operating system. The other two don't — if one of them wedges badly enough, the fix involves walking over and pressing a button, not logging in remotely. Power-on behavior across the three is similarly inconsistent, for the same reason everything else here is inconsistent: three machines with three different histories, not one buying decision.

The smallest of these three isn't even a Proxmox node — a Raspberry Pi 3B+ sits alongside the cluster running the primary DNS for the whole network, a good fit for something that needs to stay on all the time and barely sips power while it does. That's next.
How names resolve
DNS runs as a primary/secondary pair — the primary is that Raspberry Pi from the previous section, the secondary lives as a VM on the largest node. Every record for the domains I actually own is authoritative here first; anything outside that gets recursed externally rather than trusted to whatever public resolver happens to be configured — a small, deliberate split: answer what's mine locally, ask the internet only for what isn't.
The two DNS servers stay in sync the standard way a primary/secondary pair should — zone-transfer notifications, authenticated so a rogue transfer can't inject records, over the same protocol clients use to query. Edits only ever happen on the primary; the secondary exists purely so resolution keeps working if the Pi is ever down, not as a second place to make changes. It's a small, textbook piece of infrastructure, and it's worth including for exactly that reason — not everything here needs to be exotic to be worth explaining well.
How the network is carved up
The network is split into eight segments, each one a trust boundary enforced at the edge router rather than a naming convention — what a machine can reach depends entirely on which segment it's in.
Illustrative addressing below — not the real ranges.
| Segment | Purpose |
|---|---|
| Home | Personal devices — outside the infrastructure's own address space |
| Internal | The trusted application plane — most services live here |
| Data | Storage and stateful services, deliberately hard to reach directly |
| Corp | Work devices |
| CI | Build and automation workers, outbound access only |
| Public | Internet-facing — reachable only through one gateway |
| Backup | Reserved for a backup system that doesn't exist yet |
| Mgmt | DNS, hypervisor consoles, the admin-only control plane |
The interesting part isn't the list, it's the reasoning behind it:
- Data is isolated on purpose. Nothing reaches a database or the object store directly — only through explicit, named paths for the services that need them.
- Public behaves like a classic DMZ, not a doorway. It's reachable from the internet, but it can only forward to a short, explicit list of backends — it is never a general path into the trusted internal network, even for things running on the same physical machine.
- CI can reach out, but nothing trusts it to reach in. Build workers need outbound access to pull dependencies and push images; that's a completely different permission than being trusted to administer anything.
Two separate VPN networks sit alongside these segments for remote access — one for administration, one for development access — but they're routed overlays, not VLANs a peer ever directly joins, and the access model behind them belongs on /security, not here.
How traffic gets in
Three separate reverse proxies handle ingress, each one scoped to a different trust level rather than one proxy doing everything. This is probably the single decision on this page with the most "why" behind it, so it's worth explaining properly instead of just listing the three.
| Tier | Reachable from | What lives there |
|---|---|---|
| Public | The open internet (allow-listed backends only) | The only entrypoint reachable from the open internet. It forwards to a short, explicit allow-list of backends and nothing else. |
| Internal | Trusted networks only | For tools meant to be reached from trusted networks only: dashboards, monitoring UIs, day-to-day dev utilities. This is the busiest of the three by a wide margin — most things people actually use daily live behind it. |
| Management | The administration VPN only | The infrastructure control plane. Hypervisor consoles, DNS administration, network gear, hardware-level access. Reachable only over the administration VPN, never from anywhere else. |
The reasoning, as plainly as I can put it:
Compromising an app behind the internal proxy should never hand someone a path to a hypervisor console or a switch's admin panel.
That's the entire justification for the management proxy being its own instance, in its own network segment, gated behind its own VPN — not a convenience, a containment boundary. The rule of thumb I actually use when adding something new: if it can reboot a machine, touch the network configuration, or reach hardware directly, it goes behind management. Everything else is a question of audience — internal team, or the public internet. The same containment logic shows up again on /security, applied to people instead of proxies: it's the whole reason remote access is split into two separate VPNs rather than one with permission tiers.
Two edge cases worth calling out, because they're the kind of detail that actually explains the reasoning rather than just restating the rule:
- A couple of internal tools are intentionally reachable through two of these proxies at once — same backend, reached differently depending on whether the caller is an external integration (a webhook, for instance) or a teammate on the trusted network. That duplication is deliberate, not leftover inconsistency.
- The object storage service technically lives on the isolated data segment, but it's reached from outside that segment through the internal proxy rather than a direct firewall exception carved out just for it. The proxy path is the one sanctioned way in — not a shortcut around the isolation, the isolation working as intended.
Where the state lives
Everything with actual state — databases, object storage — is confined to the data segment described earlier, and access into it is deliberately narrow: only the specific hosts, proxies, and monitoring checks that need a path in have one, nothing broader.
Two pieces live there: RustFS, an S3-compatible object store, and two separate PostgreSQL instances — production and development kept fully apart rather than sharing one server with different databases on it. RustFS replaced MinIO after a license change and a community-edition UI that got noticeably worse; of the alternatives I looked at, RustFS had the best UI and is S3-compatible the same way MinIO was, so nothing built on top of it had to change. Direct database access is the exception, not the default; most things that need data go through an application layer in front of it, and the handful of things that connect directly (monitoring, a couple of trusted hosts) are named exceptions, not an open door.
What's actually running
Thirty-plus services sit on top of all of this, and the count itself isn't the interesting part — why each one is there is. The DNS pair, the edge router and switch, and the three reverse proxies are already covered above; what's below is everything else, grouped by what it's for rather than dumped into one long reference table.
Metrics storage and the alert rules that decide when something's actually wrong.
Log storage, queried the same way as the metrics next to it.
Routes every alert straight to a phone, so I hear about it before a client does.
The dashboards I actually look at every day.
Active checks on everything public-facing, independent of the metrics pipeline.
Workflow automation for the small glue jobs that don't deserve their own service.
A toolbox of the small dev utilities I'd otherwise be searching for online, one per use.
Handles the PDF merging/splitting/converting I used to reach for a random web tool for.
A UI over the Docker hosts, for when I don't want to SSH in just to check a container.
My own file cloud — replaced the Google Drive dependency this whole platform started from.
The actual photo library I use day to day, not a rented one.
A personal book-tracking project of mine — small, but it's mine end to end.
One more detail worth a mention: internally, all of this is also tied together through a single dashboard — a self-hosted "homepage" style landing page that groups every internal link in one place. It's not something the public page needs to expose directly, but it's a good aside on how the day-to-day experience of running this actually works.
From here: /security covers how access into all of this is actually controlled, and /operations covers how it's kept running day to day. None of it is finished — /roadmap is the backlog, in order, of what's still open. And once something here changes, /log is where it stops being current state and becomes history.