Infrastructure / 2025 — Present
Self-Hosted Infrastructure
A maintained Debian environment for containerized services, private administration, public routing, and repeatable deployment.

Overview
I built and maintain a Debian home-server environment for personal services and websites. It gives me a practical place to learn Linux administration, container networking, reverse proxies, DNS, and deployment by operating the whole path from a process on the server to a public hostname.
Applications are isolated with Docker and Docker Compose. Public traffic enters through Cloudflare Tunnel, while administrative services stay on separate, access-protected subdomains and are never presented as part of this portfolio.
Problem and motivation
Running software locally is different from operating it reliably. A service needs repeatable configuration, storage, routing, updates, failure recovery, and a clear boundary between public and administrative access.
The project began as a way to host personal tools. It grew into an environment for learning how those responsibilities fit together and for testing deployment choices on infrastructure I control.
Approach
I keep application configuration declarative where practical. Compose files describe service boundaries and volumes, while the reverse-proxy and tunnel layers give each public application an explicit route.
The portfolio follows the same approach: Astro produces a static build, Nginx serves it from a container bound only to 127.0.0.1, and Cloudflare Tunnel is the sole public route to that origin.
Architecture
The system is divided into three clear layers:
- Workloads — containerized applications and their persistent data.
- Origin routing — local ports and Nginx where an application needs static serving or reverse proxy behavior.
- Edge routing — Cloudflare DNS, TLS, Tunnel hostnames, and access policy.
Keeping those responsibilities separate makes it easier to replace one application without changing the public edge or exposing a private management interface.
Challenges and tradeoffs
Self-hosting trades convenience for control and responsibility. Updates, backups, observability, and network boundaries all become explicit work. I keep sensitive configuration and topology details private, so this case study explains the architecture without publishing secrets, internal addresses, or administrative links.
Result
The environment now supports the services and websites I use while giving me repeatable experience with Linux, Docker, networking, and edge routing. It remains an actively maintained system rather than a finished one-time build.
What I learned
The most useful lesson has been operational clarity: a system is easier to maintain when each component has a narrow responsibility, private surfaces remain private, and deployment can be reproduced from documented configuration.