A Kubernetes platform built on bare metal, from the hypervisor up to the workloads — owning every layer rather than delegating it to a managed service.
Each layer is deployed by hand first, then codified. The goal is to understand how it actually works before automating it.
Dual Xeon Silver 4116, 128 GB RAM, running Proxmox VE. Key-only SSH, deny-by-default firewall, TOTP on the root account.
Proxmox runs from a dedicated external SSD, booted on demand. The Windows install on the internal drives stays untouched. No dual boot, no partitioning. It also means the lab is not running around the clock: every session starts with a full boot of the cluster, which makes it a reproducibility test as much as a lab.
Three Debian VMs provisioned from the Proxmox CLI with cloud-init. One server, two agents, SQLite datastore.
Traefik as ingress controller, cert-manager issuing and renewing Let's Encrypt certificates over the DNS-01 challenge on Route 53. The cluster stays private, but every service is reachable over HTTPS on a real domain, with an IAM user scoped to a single hosted zone.
Gitea deployed via Helm as the internal forge, ArgoCD watching a single repository as the source of truth and reconciling the cluster against it.
Gitea Actions enabled, a self-hosted Gitea Runner registered against the organisation. It runs as two containers — the runner and a docker:dind sidecar sharing the socket through an emptyDir volume — with per-job container isolation.
The runner currently relies on a privileged docker:dind sidecar — a deliberate, documented trade-off, since the pipeline already depends on the Docker socket. A pod-per-job runner would be the cloud-native answer, but it ships only with the Enterprise edition. The planned improvement is to move to a daemonless, rootless builder (Buildah or Kaniko): no Docker socket, no privileged container.
Hadolint and Grype vulnerability scanning (--fail-on critical) are integrated into the CI pipeline, ahead of the image build and push to the registry. Still to come: image signing (cosign) and a move to rootless builds (Buildah / Kaniko) to remove the Docker socket dependency.
kube-prometheus-stack (Prometheus + Grafana) deployed via Helm and reconciled by ArgoCD, running inside the cluster.
Terraform and Ansible, once the manual flow is fully understood.
How the stack is built, from the disk it boots off to the cluster on top.
How a change reaches the cluster. CI writes to Git and to the registry, and stops there.