Home-Hosted Application Infrastructure
The server is a used ThinkPad in my home. The applications running on it are public on the internet. Making those two facts coexist reliably became a systems-engineering project of its own.
This is the platform beneath my portfolio, media application, and the former KXTX publishing operation. I designed the path from public DNS to application code, the path from my development machines into production, and the paths back out when I need to administer, diagnose, or recover the system. There is no managed hosting control panel hiding the important parts.
From a residential connection to the public internet
Cloudflare-proxied DNS and rate limiting form the public edge. Because the house has a dynamic IP address, a root-owned service checks it every five minutes and updates the necessary DNS records through a narrowly scoped Cloudflare token. Caddy handles origin TLS, redirects, routing, security headers, protected paths, and the handoff into isolated application runtimes.
The router and host firewall expose only the services that have a reason to exist: web traffic, a nonstandard key-only SSH endpoint, the Syncthing transport, and a WireGuard listener. Administrative interfaces for Caddy, Syncthing, and local mail remain bound to localhost. The goal is not to pretend a home network is an enterprise data center; it is to make every open path intentional, limited, and inspectable.
A laptop treated like infrastructure
The primary host is a repurposed Lenovo ThinkPad T14 running Linux, with encrypted external volumes for application data and media. It is modest hardware doing real work: serving public pages, streaming authenticated media, rebuilding catalogs, recording deployment history, and supervising the services around them.
The storage layer is defensive about physical failure. Larger media libraries can live on a second encrypted disk while remaining path-transparent to the application through bind mounts. Ingest verifies the expected filesystems, device identities, and sentinel files before it is allowed to reconcile a catalog. A missing mount fails closed instead of looking like thousands of intentional deletions.
Isolation at the application boundary
Each public site has its own PHP-FPM pool, Unix socket, filesystem boundary, access log, and Caddy rules. The portfolio process can read only its own webroot and temporary files. The media process receives the additional storage access it needs, while the application keeps catalog data, artwork, code, and raw media behind session-aware delivery endpoints.
That isolation is paired with a default-deny firewall, key-only SSH, fail2ban, restricted token permissions, hidden implementation files, explicit security headers, and recurring review of listeners, logs, software drift, peer devices, and backup coverage. I describe the result as security-hardened rather than simply “secure”: the controls are concrete, routinely checked, and designed for this environment, with their limitations documented.
Deployment without a production mystery
I author the sites on my workstations. Syncthing moves the web tree to a receive-only production folder on the server, so deployment is quick without allowing production to quietly become a competing source of truth. The live webroot contains no Git metadata.
Instead, the server records the deployed tree into a separate Git directory on a timer. That separation preserves recoverable history without putting repository internals inside a public or synchronized directory. Server-side tasks such as media ingest return generated catalogs and artwork to the authoring tree, allowing every peer to converge on the same application state.
Private access without exposing the private network
Off-site administration uses a split-tunnel WireGuard connection into the home LAN. Only the home subnets travel through it; ordinary internet traffic does not. The server handles forwarding and NAT for the tunnel, while development machines and the Mac workstation remain reachable only from the LAN or through that private route rather than through their own public SSH ports.
The normal VPN command is a wrapper that verifies the interface, routes, handshakes, pings, and SSH reachability instead of treating “the process started” as proof that the path works. It is a small example of the larger operating principle: test the outcome, not merely the command.
Operations that assume something will fail
Systemd timers and watchdogs supervise synchronization, dynamic DNS, update automation, history recording, storage sanitation, and other unattended jobs. A root-level guard catches the awkward class of failure where a user service never started and therefore never had a chance to report that it failed. The headless server writes failures to a bounded log; a workstation polls that log and raises desktop notifications.
Recovery is layered rather than magical. Automated Git history protects the deployed source, filesystem snapshots provide convenient rollback, and separate workstation backups cover another failure domain. The documentation is explicit that snapshots stored on the server's own system disk are not protection from that disk dying. The platform is built for understandable recovery, not for claiming high availability it does not have.
Where the platform ends
The custom media application is the workload that exercises the platform most deeply: authenticated range delivery, encrypted storage, guarded ingest, server-local runtime state, and mobile playback recovery. KXTX previously used the same public edge and application-hosting model for its independent publishing and commerce system. This portfolio is served by it too.
Julia's persistent agent runtime was also self-hosted, but it belongs on the other side of an important boundary. Her private game world and Linux processes were infrastructure I controlled directly; her hard problems were embodiment, process supervision, state integrity, and recovery rather than public HTTP delivery. The shared idea is ownership of the runtime, not a claim that every project traveled through the same network path.
What this demonstrates
- Public application hosting from residential, dynamically addressed infrastructure without surrendering the edge to a managed platform
- Cloudflare DNS and rate limiting, automated DDNS, Caddy TLS and routing, firewall policy, and private WireGuard access
- Per-site runtime and filesystem isolation with deliberately constrained administrative surfaces
- Encrypted multi-disk storage, mount-aware application safeguards, and failure-closed ingest behavior
- Fast synchronized deployment with a receive-only production node and Git history kept outside the live webroot
- Systemd supervision, watchdogs, failure forwarding, recurring security review, updates, backup, and documented recovery boundaries