Infrastructure
How this page reaches your browser
This portfolio is not on managed hosting. It is served from a machine I administer myself, with an encrypted tunnel to a home server for the live demos. This page shows the machines and then walks the chain, link by link.
A portfolio deployed on a managed platform proves I can run git push. This one proves the whole chain — DNS, certificates, reverse proxy, tunnel, isolated containers, backups that actually get restored — and the metal it runs on. The cost is accepted: I am the one watching memory on a 1 GB server and getting the alert when the house stops answering.
And one rule orders the rest: what you need to see cannot depend on my house. This site is static and lives on the public machine. If the home server is off, the portfolio is untouched and only the demo shows its maintenance page.
My setup
Before explaining anything, the part you can touch. Three machines, and not one of them is an abstraction: they make noise, they run warm, and one of them sits three metres from where this was written.
Core
The home server. This is where the real compute happens: the demos, their databases, and the internal monitoring.
- 12th-gen Intel · Iris Xe graphics
- 16 threads
- 46 GB of RAM
- 1 TB NVMe + 240 GB SSD + 500 GB HDD
- Ubuntu Server 24.04 LTS
It is the machine that makes the setup add up financially — renting this capacity would cost a multiple — and it is also the one part of the system that can be switched off. Which is exactly why nothing a recruiter needs to see depends on it.
VPS
The only surface the internet can touch. It terminates TLS, serves this site from disk, and proxies through to the house.
- 1 GB of RAM
- Ubuntu Server 24.04 LTS
- Caddy as the reverse proxy
One gigabyte of memory forces a decision about what does NOT get installed, which is a discipline in itself. Everything that grows — databases, queues, dashboards — lives on the far side of the tunnel.
perry
The homelab data monitor: a Raspberry Pi with a touchscreen that shows how the system is doing without opening anything.
- Raspberry Pi 4
- 8 GB of RAM
- 64 GB USB storage
- Built-in touchscreen
It is the one place where the state of the homelab is LOOKED AT rather than queried: load, temperature, containers up, tunnel health, on a screen that is always on. It costs less than a monitor and does more.
IoT
Two gadgets that hold up nothing on this site and are here anyway: small, but mine — built, soldered and debugged on the next desk over.
ESP32 · Hyperion
The TV throws light of whatever is on screen
An LED strip behind the television and an ESP32 driving it. Hyperion watches what is on screen, works out the colour of each edge zone and pushes it to the strip, so the wall takes on whatever is playing, live. The hard part was never the video: it was latency, because an ambilight that arrives late is more noticeable than one that is switched off.
ESP32 · WLED
Addressable strips on my own controller
A second ESP32, this one running WLED, for the addressable LED strips in the room: every pixel on its own, with effects, scenes and schedules. It is driven from the phone over the local network and talks to nobody’s cloud, so the day a vendor shuts its service down the lights still come on.
The chain, link by link
Seven pieces, in the order your request passes through them. One line each, and half a line more for the reason.
- 01
You, with a browser and nothing else
VisitorWhat you are reading is static HTML: no account, no cookie banner, and no JavaScript required to read a line of it.
- 02
The name resolves to a single exposed machine
DNSThe domain points at one small virtual server, and that server is the only part of the whole setup the internet can touch.
Why this way
One place to harden, and the house in no DNS record at all: a subdomain stops being a secret the moment its certificate is issued.
- 03
A reverse proxy that handles certificates on its own
Caddy · TLSIt terminates TLS, renews certificates without intervention, and publishes by moving a symlink atomically: you get the old version or the new one, never half of either.
Why this way
One block per host and none of them wildcard, which would mean keeping a token able to edit the whole domain on the exposed machine.
- 04
An encrypted tunnel home, without opening a single port
WireGuardThe demos do not run on the public server: they run at home, and the proxy reaches them through a tunnel established from the inside out.
Why this way
Zero port forwarding on the router, and both ends joined with a machine identity rather than a person’s, which would expire in six months.
- 05
Where the real compute lives
Home serverCore does the heavy work: the demos, their databases, and the internal monitoring.
Why this way
It is the one point that can be switched off, so what a recruiter needs to see is static and lives on the public machine.
- 06
Every demo in a box with the exit door shut
Hardened DockerUnprivileged containers with a read-only filesystem, and traffic towards the rest of the local network dropped by rule.
Why this way
A dedicated Docker network isolates the demos from each other but does not restrict what they can reach, and real isolation includes egress.
- 07
A public status page and a watchdog for silence
MonitoringMonitors check each service from the public server, and only the status page is published to the internet.
Why this way
The admin panel stays inside the tunnel, and on top of it runs a watchdog that checks not that something is wrong but that the system is still talking.