Home Lab Services
Everything here runs in the cluster, is reconciled from homelab-k8s-fluxcd, and gets its persistent storage as a dedicated ZFS dataset via OpenEBS ZFS-LocalPV. Postgres-backed services use CloudNativePG clusters. HTTP traffic enters through Traefik with automatic TLS.
Identity & Access
Authentik
Central SSO provider for everything behind the reverse proxy. Backed by its own CNPG Postgres cluster. Handles OIDC, LDAP, and SAML for the internal services that need it.
Development & CI/CD
GitLab CE
Self-hosted at gitlab.cherkaoui.ch. Source of truth for all my code, runs my CI pipelines, hosts the container registry, and is the Git remote that FluxCD reconciles the cluster from.
- GitLab Runner for CI jobs
- GitLab Registry for private container images
- Proton Bridge sidecar for outbound notification email via Proton Mail
- MinIO for object storage
- Backed by its own Postgres, Redis, and Gitaly instances
Sonarqube
Static analysis and code-quality gating for projects that need it. Backed by CNPG Postgres.
Networking
Headscale
Self-hosted Tailscale control server. Gives me a private WireGuard-based mesh between my devices and the cluster without depending on Tailscale's hosted control plane. Replaced my previous WireGuard-Easy setup.
Traefik
Ingress controller for the whole cluster. See Setup Details for how it's wired in.
Communication
Matrix
Self-hosted chat via Synapse:
- Synapse as the homeserver
- Element Web as the primary client
- Matrix Authentication Service (MAS) for modern OIDC-based auth
- Matrix RTC (SFU + auth service) for voice/video
- HAProxy for the federation routing
Backed by its own Postgres.
Photos & Media
Immich
Self-hosted photo and video backup. Replaces Google Photos for me and anyone in the family who wants it. Machine-learning features run as a separate microservice. Backed by CNPG Postgres and Redis.
Jellyfin
Media server for movies, TV, and music. Replaces my previous Plex install — Jellyfin is fully open source and has no phone-home.
The *arr stack
Media automation pipeline, all running under the same namespace as Jellyfin:
- Sonarr — TV show management
- Radarr — movie management
- Prowlarr — indexer aggregation
- Jellyseerr — request management on top of Jellyfin
- qBittorrent — torrent client
- FlareSolverr — Cloudflare challenge bypass for indexers
Documents & Knowledge
Paperless-ngx
Document management and OCR for everything I want to keep digitally filed. All documents live on the tank pool.
Monitoring & Uptime
Prometheus + Alertmanager
Core metrics collection and alerting. Deployed via the kube-prometheus-stack chart.
Loki + Alloy
Log aggregation. Grafana Alloy collects logs from every pod and ships them to Loki.
Grafana
Dashboards for everything: cluster health, node metrics, per-service metrics, log exploration. The unified view I actually look at day to day.
Uptime Kuma
External-view uptime monitoring. Pings every service from outside the cluster so I notice if ingress itself is broken.
Change Detection
Watches specific web pages for changes (pricing, release notes, that sort of thing) and notifies me when something moves.
Automation & Quality-of-Life
SearxNG
Privacy-respecting metasearch engine. My default search on most devices.
Wallos
Self-hosted subscription tracker — keeps me honest about what I'm paying for every month.
Game Servers
Crafty Controller
Management UI for a self-hosted Minecraft server for friends and family.
Websites
Runs in a websites namespace alongside a shared Caddy/mkdocs-serve deployment:
- cherkaoui-homepage — the root homepage at cherkaoui.ch
- hadi — my portfolio at hadi.cherkaoui.ch
- docs — this documentation site
- caddy-laura — my sister's website
Custom Apps
Scolx
A personal SaaS project of mine running in its own namespace with its own CNPG Postgres cluster, Stripe integration, and scheduled cleanup jobs.
Maintenance
Updates happen two ways:
- Renovate / Flux image automation bumps versions in the fluxcd repo
- FluxCD reconciles changes and rolls the affected deployments
If a deployment fails, Flux reports it and I fix it in Git. No manual kubectl edits — if I do one by accident, Flux reverts it on the next reconcile.