Mac Studio as a Kubernetes Compute Satellite

My K3s cluster runs on six Intel NUCs. They’re great for the 50+ containers that make up my homelab — Plex, Home Assistant, Frigate, Paperless, the usual suspects. But they’re terrible at machine learning. Four Skylake cores and 32 GB of RAM per node doesn’t get you far when Immich wants to classify 80,000 photos or Frigate wants a vision model to describe who’s at your door. The Mac Studio sitting under my desk — M1 Ultra, 64 GB unified memory — is the opposite problem. Absurd single-machine ML performance, but I don’t want to migrate my entire cluster to it. I want the K8s cluster to stay the control plane for routing, TLS, service discovery, and GitOps, while the Mac handles the heavy compute. ...

July 21, 2026 · 6 min · Rusty Bower

Automating a Smart Bird Feeder's Photo Archive with Kubernetes and Immich

My Bird Buddy smart feeder takes a photo every time a bird visits. Over a few months, that adds up to thousands of images — all sitting in Bird Buddy’s cloud app with no good way to search, organize, or back them up. I wanted them in Immich, my self-hosted photo library, organized by species and properly timestamped. The Bird Buddy app doesn’t have an export feature. But the pybirdbuddy Python library can authenticate to their API and walk the feed. So I built a two-stage pipeline: a CronJob that downloads new photos daily, and a second CronJob that syncs them into Immich. Both run in Kubernetes, and the whole thing is about 300 lines of Python. ...

July 16, 2026 · 5 min · Rusty Bower

Unit-Testing Home Automations That Run in Kubernetes

Home automations are code that controls physical things. When they break, the consequences aren’t a 500 error — they’re a garage door that won’t close in a snowstorm, or window shades that open at 3 AM, or a tablet that charges to 100% and stays plugged in for months until the battery swells. I run about 20 AppDaemon automations in my homelab, all deployed as Kubernetes ConfigMaps and tested with appdaemontestframework. The testing isn’t academic — it’s caught real bugs that would have been annoying or expensive to discover in production. ...

July 16, 2026 · 7 min · Rusty Bower

Fixing 10,000 Upside-Down Scanned Slides with a Local Vision LLM

My grandfather had about 10,000 35mm slides. I rented a SlideSnap X1 and spent a weekend feeding them through — 33 boxes worth, organized into folders by box. The scanner itself was great, but when you’re pushing through thousands of slides in a weekend, some inevitably go in upside down or backwards. No metadata, no EXIF orientation flags — just thousands of JPEGs, some right-side up, some not, sitting on a NAS. ...

February 23, 2026 · 7 min · Rusty Bower

Finding Fraud in $1 Trillion of Medicaid Data with DuckDB

CMS recently published provider-level Medicaid spending data from T-MSIS — every fee-for-service, managed care, and CHIP claim from 2018 through 2024, aggregated by billing provider, procedure code, and month. 227 million rows. $1.09 trillion in payments. I wanted to see what falls out when you run some basic fraud heuristics against it. The dataset is available at opendata.hhs.gov/datasets/medicaid-provider-spending/. The dataset The download is a single 2.94 GB parquet file with seven columns: ...

February 14, 2026 · 15 min · Rusty Bower

Building a Home Assistant Dashboard with Whole Home Audio Control

My Home Assistant dashboard has evolved significantly over the past year. What started as the default auto-generated cards has become a carefully organized interface that my whole family actually uses. Here’s how I built it, with a focus on the whole home audio system that ties everything together. Dashboard Philosophy Before diving into implementation, a few principles guided the design: Function over flash - Every card earns its screen space One-tap actions - Common tasks shouldn’t require drilling into menus Status at a glance - The overview tells you what’s happening without interaction Mobile-first - Tablets mounted around the house are the primary interface The Stack Lovelace YAML mode - Full control over layout and structure Mushroom cards - Clean, consistent UI components Custom Layout Card - Responsive grid layouts that work on any screen Stack-in-card - Grouping related controls together Overview Page The overview page is designed to answer “what’s happening right now?” at a glance: ...

January 26, 2026 · 5 min · Rusty Bower

Auto-Populating Pi-hole DNS from Kubernetes Ingresses

Managing DNS records for a homelab with dozens of services is tedious. Every time you deploy something new, you have to remember to add a DNS record. I solved this by using external-dns to automatically create Pi-hole DNS entries from Kubernetes ingress resources. The Goal When I create an ingress like this: apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: frigate annotations: external-dns.alpha.kubernetes.io/hostname: frigate.bowerha.us spec: rules: - host: frigate.bowerha.us # ... I want Pi-hole to automatically create a DNS record pointing frigate.bowerha.us to my ingress controller’s IP. No manual steps, no forgetting to update DNS. ...

January 17, 2026 · 4 min · Rusty Bower

Building a Self-Updating Dashboard with Homepage and Kubernetes

One of the challenges of running a homelab with dozens of services is keeping track of what’s running and where. I recently deployed Homepage - a modern, fully static dashboard that automatically discovers services from Kubernetes ingresses. Why Homepage? I evaluated several dashboard options including Homarr and Heimdall. Homepage stood out for a few reasons: Kubernetes-native service discovery - no manual configuration needed Real-time pod status - shows if services are actually running Clean, modern UI - dark theme, customizable layout Lightweight - just a static site with no database The Setup Homepage runs as a simple deployment in Kubernetes with a ServiceAccount that has read access to the cluster. The magic happens through ingress annotations. ...

January 17, 2026 · 3 min · Rusty Bower

From Keel to Renovate: Better Container Image Updates for GitOps

For years I used Keel to automatically update container images in my Kubernetes clusters. It worked, but as I moved to GitOps with ArgoCD, Keel’s push-based approach became a liability. I migrated to Renovate for PR-based image updates, and it’s been a significant improvement. The Problem with Keel Keel watches for new container images and updates deployments directly in the cluster. You can configure it via annotations: metadata: annotations: keel.sh/policy: major keel.sh/trigger: poll When a new image appears, Keel modifies the deployment in-place. ...

January 17, 2026 · 5 min · Rusty Bower

GitOps for Homelabs: Kustomize + ArgoCD Patterns and Pitfalls

I manage two Kubernetes environments - a home cluster (bowerhaus) and a cloud cluster (rustycloud) - using GitOps with Kustomize and ArgoCD. After running this setup for a while, I’ve learned what works, what doesn’t, and some non-obvious gotchas. The Architecture kustomize/ ├── base/ # Shared, environment-agnostic configs │ ├── media/ │ │ ├── lidarr/ │ │ ├── radarr/ │ │ └── sonarr/ │ ├── home-automation/ │ │ ├── home-assistant/ │ │ └── frigate/ │ └── data-analytics/ │ ├── prometheus/ │ └── grafana/ ├── environments/ │ ├── bowerhaus/ │ │ ├── applicationsets/ # ArgoCD ApplicationSet │ │ └── apps/ # Per-app overlays │ │ ├── frigate/ │ │ ├── home-assistant/ │ │ └── prometheus/ │ └── rustycloud/ │ ├── applicationsets/ │ └── apps/ │ ├── plex/ │ ├── sonarr/ │ └── grafana/ The key principle: base contains environment-agnostic resources, environments contain overlays that customize for each cluster. ...

January 17, 2026 · 5 min · Rusty Bower