Blog
DevOps, tools, tips, and tech
GitLab Runner on Kubernetes - Pod-Per-Job CI/CD
Running self-hosted GitLab Runner on Kubernetes with the Kubernetes executor, External Secrets for token management, and proper security hardening.
Alerting Done Right - Grafana, Crossplane, and Discord Notifications
Part 4 of my observability series: Managing alerts as code with Crossplane, routing to Discord, and the alerts that actually matter for a homelab.
Distributed Tracing - Istio, OpenTelemetry, and Tempo
Part 3 of my observability series: How distributed traces flow from Istio through OpenTelemetry to Tempo, and why 100% sampling makes sense for a homelab.
Metrics Collection - From Kafka JMX to Kubernetes Events
Part 2 of my observability series: Setting up metrics exporters for Kafka, PostgreSQL, and Redis, plus cluster-wide monitoring with Grafana's k8s-monitoring.
The LGTM All-in-One Stack - Unified Observability for Homelabs
Part 1 of my observability series: How a single container provides logs, metrics, traces, and profiling for a homelab Kubernetes cluster.
Service Mesh Adventures - Cilium, Istio Ambient, and the Ztunnel Saga
Part 4 of my homelab series: Running Cilium and Istio together, the ztunnel certificate nightmare, and hard-won lessons about service mesh on a single node.
GitOps All The Things - ArgoCD and the App-of-Apps Pattern
Part 3 of my homelab series: How ArgoCD's app-of-apps pattern manages 30+ applications with automatic sync and self-healing.
From Zero to K3s - Bootstrap Scripts and Time Sync Nightmares
Part 2 of my homelab series: Building an idempotent bootstrap script for K3s, and the VM time sync issue that broke everything.
The Great WSL Escape - Why My Homelab Runs in a Hyper-V VM
Part 1 of my homelab series: Why running Kubernetes in WSL didn't work out and how Hyper-V with mirrored networking saved the day.
Vibe Coding with Claude: The Joy and Pain of Building Without a Blueprint
How I built a complete desktop app in hours with AI-assisted development, what went wrong as it grew, and what I'd do differently next time.