Home Lab · Kubernetes · Generative AI · Platform Engineering
I run several small AI applications for real users. They live on free hosting, they work, and I have never seen their infrastructure. This is the blueprint for rebuilding all of it on one 20 GB laptop, layer by layer, with a free open-source tool at every layer, so I can learn how a production platform is actually put together: cluster, delivery, security, observability, AI serving, backup and cost. Beside every open-source pick there is a drop-down of the enterprise products that do the same job, so the lab maps directly onto what customers buy.
My applications are DrJhaGPT Pro (a technical-training studio grounded in my own articles), the Neevalay educator and parent bots, and a few smaller tools. They are Streamlit apps written in Python. They run on Streamlit Community Cloud, keep their data in Supabase, and get their model answers from Groq. Total monthly cost: zero. Total visibility into the platform underneath: also zero.
That is fine for a hobby. It is not fine if you want to understand how an enterprise runs the same thing, because an enterprise does not have a “Deploy” button. It has a cluster, a pipeline, a registry, an identity provider, a secrets vault, a policy engine, three kinds of telemetry, a backup schedule and a bill. I want to build all of that at home, break it, fix it, and then be able to draw it for a customer.
Step 0 · HardwareWhat one laptop can actually do
Before choosing tools, the honest inventory. Everything below was read from the machine with two PowerShell commands (Get-ComputerInfo and Get-CimInstance Win32_VideoController).
| Spec | This laptop | What it means for the lab |
|---|---|---|
| CPU | Intel i5-1155G7, 4 cores / 8 threads | Give the Linux side 6 threads. Running every stack at once is not the plan; running one phase’s stack at a time is. |
| RAM | 20 GB | 12 GB to Linux, 8 GB stays with Windows. Everything below fits in 12 GB only if stacks not being studied are scaled to zero. |
| GPU | Intel Iris Xe (shared memory) | No usable GPU. Local models run on CPU at 2 to 4 tokens per second. Groq and Gemini remain the fast tier, reached through the same gateway. |
| Disk | 459 GB, 111 GB free | Tight. Images, models and replicated volumes want 60 to 80 GB. Free up to 150 GB before the AI phase. |
| OS | Windows 11 Home, WSL2 present | Home edition has no Hyper-V manager, but WSL2 is a full Linux VM and that is all we need. |
Memory cap lives in one file, C:Users<you>.wslconfig. The two “experimental” lines matter on a small machine: the first hands idle RAM back to Windows, the second stops the Linux disk file from growing forever.
[wsl2]
memory=12GB
processors=6
swap=4GB
localhostForwarding=true
[experimental]
autoMemoryReclaim=gradual
sparseVhd=true
LayoutWhere everything sits
Why k3d and not minikube or Docker Desktop’s built-in Kubernetes: k3d runs the lightweight k3s distribution as Docker containers, one per node, so you get a real multi-node cluster. That is what lets you practise draining a node, replicating storage across nodes and spreading pods with anti-affinity. A full rebuild is one command and about ninety seconds.
Layer mapEvery layer: what I have today, the free pick, and the enterprise equivalent
This table is why I wrote the post. The groups follow my Kubernetes Stack Builder, so each row is one question a platform team has to answer. Column two is the truth about today. Column three is what goes into the lab, all free and open source. Column four is a drop-down: pick any product a customer might name and the line underneath tells you where it fits and what it replaces.
Reading the drop-downs: the first entry in each list is the one I would name first in a VMware or Nutanix shop; the rest are the usual alternatives in Red Hat, SUSE and public-cloud estates. “Same” in the enterprise column means the open-source tool is what enterprises actually run, often with a paid support contract.
| Layer | Current (today) | Open source, no cost (the lab) | Enterprise version |
|---|---|---|---|
| Foundation where the cluster runs | |||
| Host / hypervisor | None of mine. Streamlit Community Cloud runs the app on its own servers. | WSL2 Ubuntu 24.04 + Docker EngineA full Linux VM inside Windows 11 Home; Docker Desktop’s engine or a native install. | |
| Kubernetes distribution | None. Streamlit Cloud hides the runtime completely. | k3d (k3s in Docker), 1 server + 2 agentskind is the vanilla-upstream alternative; k3s is what runs on the edge for real. | |
| Operator console / CLI | Streamlit Cloud dashboard, GitHub web UI. | kubectl, helm, k9s, kustomizek9s is the day-2 console; learn to live in it. | |
| Cluster plumbing traffic, names, certificates, disks, network | |||
| Ingress / load balancer | Streamlit Cloud’s front door; I never see it. | Traefik (ships with k3s), later ingress-nginxInstall both once to learn why they differ. | |
| DNS and hostnames | A public *.streamlit.app name plus a wrapper page on my domain. |
sslip.io wildcard namesargocd.127.0.0.1.sslip.io resolves with zero configuration. |
|
| TLS certificates | Streamlit and Hostinger issue them; I have never held one. | cert-manager with my own CA issuerImport the CA into Windows once; every lab URL gets a green lock. | |
| Persistent storage | Supabase Postgres and its storage bucket, both cloud. | local-path (built in), then LonghornLonghorn gives replicated volumes, snapshots and backup to S3. | |
| Container network (CNI) | Invisible. | Cilium (replacing flannel)eBPF networking, NetworkPolicy and Hubble flow visibility. | |
| Security & policy who, what secrets, which rules | |||
| Identity / SSO (OIDC) | Supabase Auth plus my own role tables; one login per app. | KeycloakArgo CD, Grafana, Gitea, Open WebUI and the apps all log in through it. | |
| Secrets management | Streamlit Cloud’s secrets box and a local .env file. |
OpenBao + External Secrets OperatorSealed Secrets is the simpler first step. | |
| Admission policy | None. Anything could be deployed. | Kyverno“No untagged images”, “no root containers”, “resource limits required”. | |
| Image scanning (supply chain) | None. Streamlit builds the image; I never scan it. | Trivy in CI + Trivy Operator in-clusterHarbor bundles Trivy if you want the enterprise registry feel. | |
| Runtime threat detection | None. | FalcoAlerts when a pod spawns a shell or touches /etc/shadow. | |
| Code and secret scanning | None in the pipeline (GitHub’s basic push protection only). | Gitleaks + Semgrep as pipeline stepsFail the build if an API key is committed. | |
| Posture and benchmarks | None. | kube-bench + PolarisA CIS score for your own cluster, then fix the findings. | |
| Delivery from a git push to a running pod | |||
| Git and CI | GitHub + GitHub Actions (a nightly index refresh). | Gitea with Actions runnerGitHub-Actions-compatible workflows, one small container. | |
| Container registry | None. Streamlit Cloud builds and keeps the image. | Gitea registry, then HarborHarbor adds scanning, signing, replication and quotas. | |
| GitOps | None. A push to main deploys straight to production. |
Argo CD (app-of-apps)The spine of the lab. Every other row is a folder it syncs. | |
| Progressive delivery | None. Every deploy is all-or-nothing. | Argo RolloutsCanary 10% of users, watch the error rate, promote or roll back. | |
| Packaging | A requirements.txt; no image, no chart. |
Helm chart per app + Kustomize overlaysOne chart, three values files: lab, staging, prod. | |
| Dependency updates | Manual, when I remember. | RenovateOpens a pull request when a chart or base image bumps. | |
| Operate see it, alert on it, back it up, pay for it | |||
| Metrics and alerting | None. I find out from users. | kube-prometheus-stack (Prometheus, Grafana, Alertmanager)Two-day retention keeps it under 1.5 GB. | |
| Logs | Streamlit Cloud’s log tail, gone on restart. | Loki + Alloy collectorSingle-binary mode; query with the same Grafana. | |
| Traces | None. | Tempo + OpenTelemetry CollectorInstrument one Streamlit request end to end. | |
| LLM observability | None. I do not know which prompts cost what. | LangfusePrompts, tokens, latency and cost per user and per tool. | |
| Backup and DR | Supabase’s daily backup; I have never restored one. | Velero backing up to MinIODelete a namespace, restore it, time it. | |
| Cost (FinOps) | Zero rupees, and zero idea what it would cost. | OpenCostPer-namespace cost even on a laptop, with pretend prices. | |
| Chaos and resilience | None. | Chaos MeshKill pods, inject latency, watch the alerts fire. | |
| AI platform the model, the gateway, the memory | |||
| Model serving (inference) | Groq API (Llama-3.3-70B), Gemini as failover. Free tier. | Ollama on CPU with a 1.5B to 3B modelSlow but real; vLLM waits for a GPU. Groq stays the fast tier. | |
| AI gateway | None. Each app calls Groq directly with its own key. | LiteLLM proxyOne OpenAI-style endpoint routing to Ollama, Groq or Gemini, with keys, quotas and cost per team. | |
| Vector database | pgvector on Supabase (32,000 chunks) plus a keyword index. | pgvector on CloudNativePGSame schema as today, on a Postgres I operate. Qdrant is the dedicated alternative. | |
| Object storage (S3) | Supabase storage bucket for uploaded PDFs. | MinIOPDFs, Velero backups, Longhorn backups, model files. | |
| Chat / test UI | My own Streamlit pages. | Open WebUIA ChatGPT-style front end for the gateway, for testing models and RAG. | |
| Data pipelines | A nightly GitHub Action rebuilds the index. | Argo Workflows (cron)The PDF ingestion becomes a Kubernetes job, not a script. | |
| Application the thing users actually see | |||
| App hosting | Streamlit Community Cloud (one container, hidden). | Helm chart on k3d, behind Traefik, with SSOSame Python; a Dockerfile and a chart are the only additions. | |
| Application database | Supabase Postgres (users, roles, library, attendance). | CloudNativePG + PostgRESTPostgres operated as Kubernetes objects; PostgREST gives the same REST API Supabase does. | |
Order of workSix weekends, one folder each
Order matters more than tools. Each phase adds one group from the table and ends with a test you can actually run, so you know it is finished. Each phase is also a folder in the GitOps repository, which is what makes switching one off later a one-line change.
Cluster and first app
InstallWSL2 Ubuntu, Docker, k3d, kubectl, helm, k9s. A Dockerfile and a small Helm chart for DrJhaGPT Pro.
Done whenkubectl get nodes shows three Ready nodes and https://drjhagpt.127.0.0.1.sslip.io answers a question.
Delivery
InstallGitea with an Actions runner and its registry, Argo CD, the homelab repository laid out as app-of-apps.
A git push changes the running app and you never typed kubectl apply. From here on, nothing is installed by hand.
Observability
Installkube-prometheus-stack, Loki with Alloy, Tempo with the OpenTelemetry collector, one Grafana dashboard for the app, Alertmanager wired to ntfy.
Done whenYou delete the app pod and your phone buzzes within a minute, with the log line that explains why.
Security
InstallKeycloak as the single login, OpenBao with External Secrets holding the Groq and Supabase keys, Kyverno policies, Trivy and Gitleaks in the pipeline, cert-manager with your own CA.
Done whenAn image with a critical CVE fails the build, an untagged image is refused at admission, and every console opens with the same login.
AI platform
InstallOllama with a 3B model, LiteLLM, CloudNativePG with pgvector, MinIO, Langfuse, Open WebUI, and the PDF ingestion as an Argo Workflows cron.
Done whenDrJhaGPT answers through LiteLLM from the local model, falls back to Groq when told to, and Langfuse shows the cost of each question.
Day 2
InstallCilium in place of flannel, Longhorn, Velero to MinIO, Argo Rollouts, Chaos Mesh, kube-bench, OpenCost.
Done whenYou delete the apps namespace and restore it from Velero, run a 10% canary and roll it back, and can read the CIS score of your own cluster.
What “nothing by hand” looks like
Phase 2 is the one that changes how you work. After it, every change follows the same loop, and every later phase only adds a gate or a sensor to it.
Memory budget, honestly
| Stack | RAM at rest | Note |
|---|---|---|
| k3d cluster (3 nodes) | 1.5 GB | k3s is small; that is the point of it. |
| Gitea + Argo CD | 1 GB | Always on. They are the lab. |
| Monitoring (trimmed) | 1.5 GB | Two-day retention, single-binary Loki, no Grafana persistence. |
| Keycloak + OpenBao | 1.3 GB | Keycloak is a Java process; give it a real limit. |
| Ollama with a 3B model | 2.5 to 4 GB | The single biggest tenant. Scale to zero when not studying AI. |
| Postgres, MinIO, Langfuse, LiteLLM | 1.5 GB | |
| My apps | 1 GB | Streamlit is heavier than it looks. |
| Total | about 10 to 11.5 GB | Inside the 12 GB cap, with no headroom. Run phases 3 to 6 as profiles you switch on and off. |
What to leave out, on purpose
Kubeflow, KServe, Backstage, Istio and GitLab are all real production tools. They are also each heavier than the whole rest of the lab, and none teaches anything the table above does not. Add them when the laptop becomes a second-hand server.
Day oneFirst three commands
Inside the Ubuntu terminal, once Docker is reachable:
# install k3d
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
# a 3-node cluster with ports 80 and 443 mapped to the laptop
k3d cluster create homelab --servers 1 --agents 2
-p "80:80@loadbalancer" -p "443:443@loadbalancer"
--k3s-arg "--disable=traefik@server:0"
kubectl get nodes
Disabling the bundled Traefik is deliberate: the ingress controller and the CNI are the first two things the GitOps repository will install, which is exactly the habit the lab is meant to build.
homelab repository itself, phase by phase.Disclosure: DrJhaGPT Pro and the Neevalay bots are my own tools. Product names in the drop-downs are the vendors’ current names at the time of writing; several of the VMware products have been renamed under VCF 9 and the older Aria and Tanzu names are given in brackets where people still use them. Memory figures are what I measured on this laptop and will differ on yours.







DrJha