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
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.
A NAS and my first server. Photo: Ben Matheja
A wall cabinet. Photo: Ben Matheja
The first rack, used Fujitsu servers. Photo: Ben Matheja
The RX2540 M1, opened up. Photo: Ben Matheja
One M2 left, small PCs beside it. Photo: Ben Matheja
The first own build in a 4U case. Photo: Ben Matheja
Architecture
Architecture, simplified
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
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
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
Backups that restore
Modular restic backups defined as code per application, with restores tested rather than assumed.
- restic
- ansible
- backup
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
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
okf
Tooling for the Open Knowledge Format: backfills frontmatter, derives links and runs conformance checks on a Markdown vault.
- cli
- pkm
- python
vk
Installs shared skills, commands and templates into a vault, rendered for each agent the vault uses. One source, many agents.
- cli
- agents
- python
Renovate for everything
Self-hosted Renovate across every repository: container tags, Helm charts, OpenTofu providers with lock files, pinned CI images.
- renovate
- opentofu
- gitlab
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
This site's quality gates
Visual regression, axe and a publishing guardrail run on every merge request, before the redesign lands.
- playwright
- axe
- jekyll