The apps

One set of web tools, four products

FrameworkNext.js 16 · React 19 · TypeScriptThe tools I build web apps with. Pages are prepared on the server before they reach your browser, and each app is packaged as a container (a self-contained, ready-to-run copy). Everything is written in TypeScript, which catches mistakes before the code runs. Tailwind CSS handles the styling. This site, SouthpawStrings, the orchestrator’s dashboard and the MiSTer Library all use them.
My own library@denley/desk-engineThe window manager I separated out of SouthpawStrings: the code behind the desktop you may be looking at right now. All four products use it, installed from my own self-hosted store of code packages (an npm registry). Read the case study.
DataPostgreSQL 16, backed up and recoverablePostgreSQL databases, run by CloudNativePG, a tool that sets up and looks after them. Backups are checked, and the products that need it can be restored to any point in time. Sensitive user data is stored encrypted. Blind indexes let the app still find a record without decrypting the data.
AI, with checksAI that works under an engineerAI agents speed up the engineering in every project here, within clear limits. A person reviews the work and approves the decisions, and there is a record of the evidence. The AI Orchestrator is that idea built as software.

Where it runs

Self-hosted, signed-in and kept separate

Public services run on a dedicated server from a hosting provider, using Kubernetes (k3s). Kubernetes is software that runs apps in containers and keeps them running. Visitors arrive through Cloudflare Tunnels, so the app server itself is never open to the internet. Private areas sit behind Cloudflare Access, which makes everyone sign in first, wherever they connect from. Home-lab services are kept apart from the public ones. They connect only over an encrypted private link, and only where a service really needs it.

The tools for storing and building code are self-hosted too. My own Gitea server holds every repository, runs CI (automatic checks and builds on each change), and stores the finished containers and code packages. Containers are built on a separate build server, not on the machine that manages the cluster. Releases go out through scripts with built-in checks. Each script previews its changes by default and needs explicit confirmation before it touches the live service. Each release is pinned to its exact build by a unique fingerprint (a digest), and comes with a new version number and changelog entry.

Services report their own health and readiness, which the release checks use. Umami analytics count page views. It runs through this site’s own address, uses no third-party trackers, respects do-not-track, and doesn’t follow anyone around the web. The old home-lab monitoring dashboard still exists, but it’s switched off. It can no longer see the network, so leaving it on would only pretend to monitor it.