← Back to all posts

The Platform Apps That Make My Homelab Usable

April 3, 2026

#homelab #kubernetes #traefik #argocd #external-dns #1password

Part 3 of a short homelab series. Part 1 covers the hardware, and Part 2 covers the Kubernetes and GitOps layer underneath these apps.

Once the cluster was running, the next question was whether it was actually pleasant to use.

Getting Kubernetes running is the easy part. The harder part is making app exposure, DNS, and secret handling consistent enough that adding one more service does not create another pile of manual work.

For me, that came down to a small set of platform applications: Traefik at the front, ExternalDNS to keep records aligned with what the cluster exposes, 1Password as the main secret source, and Cloudflare as the DNS provider behind it.

None of these tools are unusual. That is the point. I need a few proven components that remove recurring friction.

The Core Tools In This Stack

These are the platform tools that make the day-to-day shape of the homelab feel consistent instead of improvised.

What Counts As Platform Infrastructure Here

In this homelab, I think of platform infrastructure as the layer that makes workloads reachable, configurable, and repeatable before I think about the workloads themselves.

That includes things like:

I do not treat those as optional extras. They define what using the cluster feels like in practice.

If I deploy an app and still need to wire a hostname by hand, copy a secret into the cluster manually, and remember the reconcile order myself, then Kubernetes is running but the platform is not doing much for me.

That is why I group Traefik, ExternalDNS, 1Password, and Cloudflare into the same conversation. When an application is declared, I want it reachable through a predictable entry point, under the expected DNS name, with the credentials it needs.

Why Traefik Sits At The Front

Traefik is the first platform application I care about once the cluster is alive because most other usability improvements depend on a stable ingress layer.

I use it for the obvious reason: something needs to sit at the front and route traffic to the right services. The more important part is that Traefik gives me one consistent way to expose applications. That consistency matters more than any specific ingress feature.

In a small environment, most operational friction does not come from advanced traffic engineering. It comes from repeatedly asking, “how do I expose this app here again?” I want the answer to be boring.

An ingress that looks like this is enough to express the shape clearly:

metadata:
  annotations:
    external-dns.alpha.kubernetes.io/hostname: <app-name>.<internal-zone>
spec:
  ingressClassName: traefik

That is a small amount of YAML, but it represents a bigger platform benefit. The application declares the hostname it expects and which ingress layer is responsible for serving it. Once that becomes the normal path, adding another internal service stops feeling like bespoke infrastructure work.

Traefik also fits the rest of the stack. It is capable, common, and easy to reason about. I am not trying to build a multi-tenant edge platform at home. I am trying to keep ingress understandable enough that I do not have to re-learn my own decisions every time I expose something new.

Why DNS And Secrets Belong In The Same Conversation

DNS and secrets are different concerns technically, but they create the same kind of operator pain when they are handled manually.

If DNS is manual, applications are harder to reach than they should be. If secret distribution is manual, applications are harder to configure than they should be. In both cases, the real problem is recurring uncertainty.

ExternalDNS closes the gap between declared ingress and actual DNS state. Instead of treating DNS records as a separate checklist, I want the cluster to express the intended hostname and let ExternalDNS reconcile that into Cloudflare.

That removes a common kind of homelab drift: the cluster says one thing, the DNS provider says another, and I only notice when something breaks or a rebuild leaves old records behind.

1Password solves a different part of the same story. I use it as the source of truth for application secrets, with the Connect and operator flow bridging that data into Kubernetes.

I do not want long-lived application credentials scattered across handwritten manifests or copied into the cluster by habit. I want secret values to stay in a dedicated secrets system, and I want Kubernetes to consume them through a repeatable path.

That keeps the homelab closer to the operating model I actually want:

Cloudflare is part of this picture because it is the external DNS control point ExternalDNS talks to. Once that connection exists, DNS updates stop being a separate operational step.

How These Pieces Depend On Each Other

The useful way to think about these tools is as a dependency chain.

Traefik gives the cluster a standard ingress target. ExternalDNS watches the objects that describe exposure and turns them into DNS records in Cloudflare. 1Password provides the secret material workloads and supporting controllers need without putting those values in Git. Argo CD gives me a clean way to express the ordering so that all of this settles in the right direction.

That ordering matters because platform applications are often consumers of each other.

I do not need a complicated dependency system for that. Sync waves are usually enough:

metadata:
  name: external-dns
  annotations:
    argocd.argoproj.io/sync-wave: "3"

I like this because it keeps the intent visible without pretending Argo CD is doing something more elaborate than it is. The platform layer lands first, then the applications that depend on it.

This is also why I do not think about these tools independently anymore. If Traefik exists without DNS automation, I still feel friction. If DNS automation exists without a stable ingress pattern, I still feel friction. If both exist but secret handling is inconsistent, I still feel friction.

What This Stack Buys Me Day To Day

The main benefit of this stack is that it removes a lot of small, repeated decisions.

When I add a service, I do not want to re-enter the same operational loop every time. I want one ingress path, one DNS reconciliation path, and one secret consumption model that fits the rest of the cluster.

That buys me a few practical things immediately:

More importantly, it changes the feel of the homelab. The cluster stops being just a place where containers happen to run and starts feeling like a coherent platform.

That is what I want from this environment: a platform layer that makes the rest of the stack pleasant enough to operate that I keep using it instead of working around it.

Traefik, ExternalDNS, 1Password, and Cloudflare are enough to get me there.