Lab · the Mittbachweg platform

A small platform, run like a real one.

Mittbachweg is my homelab and the name of everything I build on it. I publish apps through Cloudflare Tunnels, put Cloudflare Access and Authentik in front of them, and run the platform on Proxmox and Talos Kubernetes. Tailscale ties my devices to the home network. This site runs on it, too.

  • Everything as code
  • Apps published via tunnels
  • Access and SSO in front of apps
  • Renovate keeps it current

The homelab, 2020 to 2026

The current rack: a power strip and a UniFi switch with green patch cables at the top, two small HP PCs and a Synology NAS on shelves, two 4U servers with blue drive caddies below; the host labels are blurred.
Today. Photo: Ben Matheja

It started in 2020 with a NAS and a Fujitsu TX120 S3 on a shelf, running the UniFi controller and a few Docker containers on bare-metal Ubuntu.

In 2024 I bought used Fujitsu rack servers: an RX2540 M1 and two RX2530 M2. The M1 was so loud that I heard it in bed with the door of the utility room closed, so it had to go. The RX2530s were a different beast. I moved the best parts into one of them and sold the other as a barebone, which left one machine with two CPUs and 176 GB of DDR4. It handled anything I gave it, but its power draw did not suit a lab that runs around the clock. So I consolidated onto consumer hardware I build myself: quieter, cheaper to run, and easy to replace one part at a time.

The photo shows the rack as it stands now. Below, how it got here, oldest first.

  1. A white two-bay Synology NAS on top of a black Fujitsu TX120 S3 tower server, next to a Fritz!Box router and a Raspberry Pi in a tangle of white cables.
    A NAS and my first server. Photo: Ben Matheja
  2. A small black wall cabinet with a network switch, a patch panel and a single Fujitsu server.
    A wall cabinet. Photo: Ben Matheja
  3. A grey 19-inch rack with a Synology NAS on a shelf above two Fujitsu rack servers.
    The first rack, used Fujitsu servers. Photo: Ben Matheja
  4. The opened Fujitsu RX2540 M1 rack server in its cardboard box, with two heat sinks, memory slots, fans and the PCIe riser cards visible.
    The RX2540 M1, opened up. Photo: Ben Matheja
  5. A grey rack cabinet with a switch, small PCs, a Synology NAS and a rack server, the glass door open.
    One M2 left, small PCs beside it. Photo: Ben Matheja
  6. Close-up of a rack with a Synology NAS, a 1U server with drive bays and a 4U server chassis with blue drive caddies.
    The first own build in a 4U case. Photo: Ben Matheja

Architecture

Architecture, simplified

Mittbachweg platform layers Five layers from the internet inward. Edge: Cloudflare DNS, Tunnels and Access applications. Identity: Authentik with OIDC and forward auth. Platform: Proxmox, Talos Kubernetes with Flux, OpenTofu and Vault. Connectivity: Tailscale. Operations: observability, Renovate and CI/CD. Edge Cloudflare DNSrecords point at the tunnel Tunnelsthe connector dials out Access applicationsa policy per app Identity AuthentikOIDC where apps support it Forward authwhere they don't Platform Proxmox VEhosts, via Ansible Talos Kubernetesreconciled by Flux from Git OpenTofudefines the layers as code Vaultsecrets, login via Authentik Connectivity Tailscalesubnet routers to the home network, ACL as code, an off-site probe host Operations ObservabilityPrometheus, Loki, Tempo, Grafana Renovateupdate MRs across my repos CI/CDGitLab CI, releasekit Mittbachweg platform layers Five layers from the internet inward: edge, identity, platform, connectivity and operations. Edge DNS · Tunnels · Accessoutbound tunnel, a policy per app Identity AuthentikOIDC or forward auth Platform Proxmox · Talos · FluxOpenTofu defines it, Vault holds secrets Connectivity Tailscalesubnet routers, ACL as code Operations Observability · Renovate · CI/CDPrometheus, Loki, Tempo, releasekit
Five layers, from the internet inward. No hostnames, no addresses: the shape, not the map.

Edge

I publish apps through Cloudflare Tunnels. The connector dials out to Cloudflare, so a published app doesn't need a port forward, and DNS records point at the tunnel. Where an app needs it, a Cloudflare Access application sits in front with its own policy: an email allow rule, a bypass for known source IPs. All of it is OpenTofu code.

Identity

Authentik is my identity provider. Apps that speak OIDC get OIDC. The rest get Authentik forward auth through a proxy outpost. Authentik's own login sits behind an Access application as well.

Platform

Proxmox hosts run the virtual machines, among them the Talos nodes of my Kubernetes cluster. Flux reconciles the cluster from Git, Cilium does the networking. OpenTofu builds the VMs and the Cloudflare, Authentik and Tailscale settings, Ansible configures the hosts. Vault holds the secrets and lets me log in through Authentik.

Connectivity

Tailscale is the VPN between my devices, the home network and an off-site probe host. Subnet routers bring the home network into the tailnet. The ACL is OpenTofu code, and the probe host may only reach internal services on port 443.

Operations

Prometheus, Loki, Tempo and Grafana cover metrics, logs and traces, with Alloy shipping them and alert rules kept as code. Renovate opens update merge requests across my GitLab group. GitLab CI runs the pipelines, and releasekit cuts the releases of this site.

How an app is hosted

Two ways in, and every app takes one of them.

Path 1

On the Kubernetes cluster

Gateway API (Cilium) → Service → Pods

The cluster runs Talos Linux on Proxmox VMs, built by OpenTofu. Flux reconciles everything from Git, cert-manager issues the certificates, and External Secrets pulls credentials from Vault. This is the home of the stateless and the many: the MCP servers, the agent workers and the CI runners.

Path 2

A VM with Docker Compose

Traefik (Let’s Encrypt) → containers on the same VM

Each VM runs one Traefik. It gets its certificates from Let’s Encrypt through the Cloudflare DNS challenge and routes to the other containers by their labels, with Authentik forward auth in front of anything sensitive. An Ansible role renders the Compose stack, fetches the secrets from Vault at deploy time and pins every image version for Renovate to bump. Apps with real state live here: GitLab, Immich, Authentik, the media stack.

Either way, a public app gets one more hop at the front: a Cloudflare Tunnel connector next to it, so nothing at home listens on the internet. On the VMs a sidecar backs up the volumes and Uptime Kuma takes its checks from the container labels.

Projects

10 projects · updated October 2026

Running

Kubernetes on Talos

An immutable Kubernetes cluster on Proxmox, reconciled by Flux from Git. Cilium for networking, certificates and DNS fully automated.

  • talos
  • flux
  • cilium
Running

Single sign-on everywhere

Authentik as the identity provider: OIDC where apps support it, forward auth where they don't, and Vault logins without root tokens.

  • authentik
  • vault
  • oidc
Running

Backups that restore

Modular restic backups defined as code per application, with restores tested rather than assumed.

  • restic
  • ansible
  • backup
Running

Observability

Metrics, logs and traces in one place, with alert rules that are reviewed like code and retention that fits the disks.

  • prometheus
  • loki
  • tempo
Running

MCP gateway and servers

One authenticated endpoint that multiplexes small MCP servers for documents, photos, bookmarks and observability, so agents can use the lab safely.

  • mcp
  • python
  • sso
Released

okf

Tooling for the Open Knowledge Format: backfills frontmatter, derives links and runs conformance checks on a Markdown vault.

  • cli
  • pkm
  • python
Released

vk

Installs shared skills, commands and templates into a vault, rendered for each agent the vault uses. One source, many agents.

  • cli
  • agents
  • python
Running

Renovate for everything

Self-hosted Renovate across every repository: container tags, Helm charts, OpenTofu providers with lock files, pinned CI images.

  • renovate
  • opentofu
  • gitlab
Rolling out

Mittbachweg brand

A small identity for the platform: design tokens, a mark drawn from code, and rules for apps, CLIs and this site.

  • design tokens
  • svg
Building

This site's quality gates

Visual regression, axe and a publishing guardrail run on every merge request, before the redesign lands.

  • playwright
  • axe
  • jekyll