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, and security headers. It protects private paths and passes allowed requests 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. It serves public pages and streams authenticated media. It also rebuilds catalogs, records deployment history, and supervises 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 and Unix socket. Filesystem boundaries, access logs, and Caddy rules are separated as well. 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, and fail2ban. Restricted token permissions, hidden implementation files, and explicit security headers add controls at the application boundary. Recurring review covers listeners, logs, and software drift. It also covers 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 manual-start, split-tunnel WireGuard connection from a client app on my administration laptop. Only the home subnets travel through it; ordinary internet traffic does not, and the server handles forwarding and NAT for the tunnel.

After the client reports the tunnel active, I run an actual command through it and confirm that the server responds. I do not rely on the status indicator alone. It is a small example of the larger operating principle: test the outcome, not merely the connection state.

Operations that assume something will fail

Systemd timers and watchdogs supervise synchronization, dynamic DNS, and update automation. The same supervision extends to 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 and pushes new entries outward over key-only SSH once a minute. A workstation’s local notifier reads only its own delivered inbox and raises a desktop alert. It never reaches back into the server to poll for failures.

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. It relies on authenticated range delivery, encrypted storage, guarded ingest, and server-local runtime state. Mobile playback recovery exercises another layer of the stack. 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.

The Persistent AI Agent Runtime was also self-hosted. It controlled a private game client through deterministic workers, an event bridge, and supervised recovery. That project exercised process operation and state integrity rather than public HTTP delivery. It shared the responsibility for operating a runtime, while using a separate application and 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