From f5ae4a2746b87609ac16a1ca8a641bbd28c00b3a Mon Sep 17 00:00:00 2001 From: juvdiaz Date: Tue, 26 May 2026 22:49:22 -0600 Subject: [PATCH] Update blog with latest homelab additions --- apps/website/blog.php | 127 ++++++++++++++++++++++++++++++++------ apps/website/lang/en.php | 34 +++++++--- apps/website/lang/nah.php | 17 +++-- 3 files changed, 145 insertions(+), 33 deletions(-) diff --git a/apps/website/blog.php b/apps/website/blog.php index 5c0210e..176bf21 100644 --- a/apps/website/blog.php +++ b/apps/website/blog.php @@ -12,6 +12,10 @@ $activityKeys = [ 'blog_activity_7', 'blog_activity_8', 'blog_activity_9', + 'blog_activity_10', + 'blog_activity_11', + 'blog_activity_12', + 'blog_activity_13', ]; $todoKeys = [ @@ -27,6 +31,9 @@ $todoKeys = [ 'blog_todo_10', 'blog_todo_11', 'blog_todo_12', + 'blog_todo_13', + 'blog_todo_14', + 'blog_todo_15', ]; $stackKeys = [ @@ -43,6 +50,9 @@ $stackKeys = [ 'blog_stack_11', 'blog_stack_12', 'blog_stack_13', + 'blog_stack_14', + 'blog_stack_15', + 'blog_stack_16', ]; $treeHref = 'homelab-tree.php?lang=' . urlencode($lang); @@ -106,12 +116,25 @@ $stackSourceLinks = [ 'blog_stack_12' => [ ['label' => 'provisioning/main.tf', 'path' => 'bootstrap/provisioning/main.tf'], ['label' => 'lab.sh Pimox pipeline', 'path' => 'lab.sh'], + ['label' => 'provisioning README', 'path' => 'bootstrap/provisioning/README.md'], ], 'blog_stack_13' => [ ['label' => 'preseed.cfg', 'path' => 'bootstrap/provisioning/templates/preseed.cfg.tftpl'], ['label' => 'golden-node prepare', 'path' => 'bootstrap/provisioning/templates/golden-node-prepare.sh.tftpl'], ['label' => 'prepare-template', 'path' => 'bootstrap/provisioning/templates/prepare-template.sh.tftpl'], ], + 'blog_stack_14' => [ + ['label' => 'lab.sh worker storage guardrail', 'path' => 'lab.sh'], + ['label' => 'README Pimox defaults', 'path' => 'README.md'], + ], + 'blog_stack_15' => [ + ['label' => 'lab.sh OpenWrt pipeline', 'path' => 'lab.sh'], + ['label' => 'README OpenWrt notes', 'path' => 'README.md'], + ], + 'blog_stack_16' => [ + ['label' => 'platform/main.tf', 'path' => 'bootstrap/platform/main.tf'], + ['label' => 'README monitoring', 'path' => 'README.md'], + ], ]; function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $sourceBase): void { @@ -202,22 +225,22 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
- + Homelab architecture map - Git push enters Gitea, Gitea Actions validates and builds app images, OpenTofu manages the cluster and provisioning layers, Debian serves PXE and preseed content, Pimox builds Debian VM templates, Argo CD syncs manifests, and the OCI edge routes traffic into Kubernetes services. + Git push enters Gitea, Gitea Actions validates and builds app images, OpenTofu manages the cluster and provisioning layers, Debian serves PXE and preseed content, Pimox builds Debian VM templates and worker clones on NVMe storage, OpenWrt can run as an opt-in firewall VM, Argo CD syncs manifests, and the OCI edge routes traffic into Kubernetes services. - + Source, validation, and images - + Debian node 192.168.100.68 - + Edge access and workloads @@ -285,15 +308,22 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so Argo CD - container-registry, website - gitea and demos-static apps + registry, gitea, monitoring + website and demos-static apps - + + + Monitoring stack + Prometheus, Grafana, Loki + Mimir, Promtail, exporters + + + Storage and backups - OpenEBS retained hostpath PVs - Gitea dumps and external SSD + OpenEBS retained PVs + Gitea dumps and monitoring data @@ -322,13 +352,22 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so Orange Pi 5 Plus Pimox - VM 9000 Debian template - OVMF, virtio-scsi, qemu agent - future worker clones - waiting on more disk + VM 9000 template on local + workers on nvme_thin_pool + OVMF, virtio-scsi, qemu agent + idempotent qm automation - + + + OpenWrt firewall VM + VM 9050, opt-in only + vmbr0 WAN, vmbr1 LAN + simple firewall path + DHCP optional, VLANs later + + + Local registry :30500 php-website and demos-static @@ -340,17 +379,20 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so - + + + + - + push workflow @@ -361,10 +403,11 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so serve boot join path Pimox template + firewall VM sync apps secure tunnel service traffic - image pulls + image pulls
@@ -574,6 +617,54 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so

+ +
+
+ +
+

+ +

+
+ +
+
+ +
+

+ +

+
+ +
+
+ +
+

+ +

+
+ +
+
+ +
+

+ +

+
diff --git a/apps/website/lang/en.php b/apps/website/lang/en.php index 1fb7f33..02e7937 100644 --- a/apps/website/lang/en.php +++ b/apps/website/lang/en.php @@ -55,13 +55,13 @@ return [ 'blog_kicker' => 'Homelab field notes', 'blog_title' => 'I accidentally built a tiny CI/CD platform', - 'blog_subtitle' => 'A casual conversation about how a Debian box, a Raspberry Pi, an Orange Pi 5 Plus running Pimox, an OCI edge host, and a suspicious amount of stubbornness became a repeatable Kubernetes delivery path.', + 'blog_subtitle' => 'A casual conversation about how a Debian box, a Raspberry Pi, an Orange Pi 5 Plus running Pimox, an OCI edge host, a Debian 13 VM template, and a small OpenWrt firewall plan became a repeatable Kubernetes delivery path.', 'blog_speaker_question' => 'Future me, judging', 'blog_speaker_answer' => 'Me, holding coffee', 'blog_q1' => 'Be honest: why build all this instead of just running a couple containers like a normal person?', 'blog_a1' => 'Because apparently I looked at "host a website" and thought, "what if this had a control plane, GitOps, retained storage, an image registry, and several new ways to embarrass myself?" The real goal was practice: provision the infra, keep config in Git, deploy with automation, break it, fix it, and make sure I could rebuild it without relying on shell history and vibes.', 'blog_q2' => 'Why kubeadm? Were managed clusters too emotionally stable?', - 'blog_a2' => 'Pretty much. kubeadm keeps the cluster close to the metal, which is a polite way of saying I get to see every sharp edge. The Debian node runs the control plane, the Raspberry Pi joins as an arm64 worker, and Pimox on an Orange Pi 5 Plus now gives me a path to add Debian 13 arm64 VM workers. Suddenly networking, storage, container runtimes, certs, and node recovery are not mysterious cloud magic. They are my problem.', + 'blog_a2' => 'Pretty much. kubeadm keeps the cluster close to the metal, which is a polite way of saying I get to see every sharp edge. The Debian node runs the control plane, the Raspberry Pi joins as an arm64 worker, and Pimox on an Orange Pi 5 Plus now gives me a repeatable way to add Debian 13 arm64 VM workers. Suddenly networking, storage, container runtimes, certs, and node recovery are not mysterious cloud magic. They are my problem.', 'blog_q3' => 'So where is the CI/CD part hiding?', 'blog_a3' => 'It is small, but it is real. OpenTofu brings up the cluster, platform, apps, and edge layers. Argo CD watches Git and keeps the cluster honest. Docker Buildx builds the PHP website for linux/arm64, pushes it to the local registry, and then the workload rolls forward. No enterprise dashboard fireworks, just a clean loop that says: Git changed, image built, cluster updated, nobody had to kubectl-edit anything at 2 AM.', 'blog_q4' => 'Why run your own registry and Gitea? Was the simple option unavailable?', @@ -73,10 +73,14 @@ return [ 'blog_q7' => 'Can the current cluster actually handle all that, or are we about to smoke the Pi?', 'blog_a7' => 'The Pi survives because the demos are intentionally local-first and now ship as a separate static artifact. The website pod stays a portfolio shell, the demos-static pod serves static bundles, and the user browser does the expensive work. If I later ship real ONNX object detection, Transformers.js, or full video transcoding models, those must lazy-load in the browser or move to a beefier node. The Raspberry Pi is brave, but it is not a GPU wearing a tiny hat.', 'blog_q8' => 'So the lab can now build its own worker nodes?', - 'blog_a8' => 'Mostly, yes. Debian now runs a small provisioning layer with dnsmasq, nginx, PXE boot files, GRUB, and a Debian 13 arm64 preseed. OpenTofu talks to Pimox through qm, creates VM 9000, boots it from the network, installs the OS, runs the golden-node prep, disables swap, verifies cgroups, installs containerd and kubeadm tooling, then seals the VM as a template. The only current blocker for cloning more workers is wonderfully physical: add more disk space.', + 'blog_a8' => 'Yes, and now with fewer crossed fingers. Debian runs a provisioning layer with dnsmasq, nginx, PXE boot files, GRUB, and a Debian 13 arm64 preseed. OpenTofu talks to Pimox through qm, creates VM 9000 on local storage, boots it from the network, installs the OS, runs golden-node prep, disables swap, verifies cgroups, installs containerd and kubeadm tooling, then seals it as a template. Worker clones are idempotent by VMID and now land on nvme_thin_pool, so local storage stays reserved for the template.', + 'blog_q9' => 'And OpenWrt is joining the story too?', + 'blog_a9' => 'Only as a simple firewall, not as a networking science project. The pipeline can create an opt-in OpenWrt ARM SystemReady VM, attach vmbr0 as WAN and vmbr1 as LAN, and configure the LAN side without rewriting Orange Pi host networking. DHCP stays optional, and VLANs wait until there is a managed switch and a local test window.', + 'blog_q10' => 'What changed on the observability side?', + 'blog_a10' => 'Monitoring moved from "someday" to "running." The platform now has Prometheus, Grafana, Loki, Mimir, Promtail, node-exporter, and kube-state-metrics. The next useful step is not installing more dashboards; it is choosing the few alerts that would actually wake me up for the right reasons.', 'blog_stack_title' => 'Technologies and why they are here', 'blog_stack_1' => 'Debian Linux is the steady adult in the room: control plane host, deployment workstation, PXE/preseed server, and the place where OpenTofu, Docker, kubeadm, and the scripts do their thing.', - 'blog_stack_2' => 'Raspberry Pi adds the current arm64 worker, while Pimox on the Orange Pi 5 Plus gives the lab a VM-based expansion path once there is enough storage.', + 'blog_stack_2' => 'Raspberry Pi adds the current arm64 worker, while Pimox on the Orange Pi 5 Plus gives the lab a VM-based expansion path. The template stays on local storage and Kubernetes worker clones go to nvme_thin_pool.', 'blog_stack_3' => 'OpenTofu makes the cluster, platform, apps, edge, and provisioning layers repeatable, because "I swear I remember the command" is not a disaster recovery strategy.', 'blog_stack_4' => 'Calico handles pod networking, and OpenEBS hostpath storage keeps the important data around after rebuilds, because deleting everything by accident is only funny once.', 'blog_stack_5' => 'Argo CD is the GitOps referee: manifests live in Git, the cluster follows along, and manual drift gets side-eyed back into place.', @@ -86,16 +90,19 @@ return [ 'blog_stack_9' => 'The newer demos cover network jitter graphs, local JSON/JWT/log tools, an architecture simulator, an offline traveler converter, a redactor prototype, sentiment analysis, and model-drift simulation.', 'blog_stack_10' => 'The heavier ML demos are designed as client-side Wasm/ONNX/Transformers.js candidates, not server-side jobs. That keeps the homelab app boring to operate, which is secretly the whole point.', 'blog_stack_11' => 'The demo code now builds into its own demos-static image and Argo CD app, exposed at /demo-apps/. The PHP website only owns the catalog link, which is much less cursed.', - 'blog_stack_12' => 'The Pimox worker pipeline uses qm over SSH to create an OVMF/virtio-scsi Debian 13 arm64 VM, wait for qemu-guest-agent, seal it, and convert VM 9000 into a reusable template.', + 'blog_stack_12' => 'The Pimox worker pipeline uses qm over SSH to create an OVMF/virtio-scsi Debian 13 arm64 VM, wait for qemu-guest-agent, seal it, and convert VM 9000 into a reusable template on local storage.', 'blog_stack_13' => 'The golden image bakes in Kubernetes prerequisites: swap disabled, cgroup boot options checked, kernel modules loaded, containerd configured for systemd cgroups, kubeadm/kubelet/kubectl installed, and qemu-guest-agent enabled.', + 'blog_stack_14' => 'Worker clone automation is count-based and idempotent: LAB_PIMOX_WORKER_COUNT=1 means ensure VM 9010 exists, not create a fresh worker on every run. New workers are refused if the target storage is local.', + 'blog_stack_15' => 'OpenWrt is handled separately from the Debian golden-node template. The lab downloads the upstream ARM SystemReady EFI image, imports it as VM 9050 on nvme_thin_pool, and keeps it disabled unless LAB_OPENWRT_VM=true is set.', + 'blog_stack_16' => 'The monitoring layer now includes Prometheus Stack, Grafana, Mimir, Loki, Promtail, node-exporter, and kube-state-metrics, giving the lab metrics and logs without putting heavy traffic analysis on the firewall.', 'blog_arch_kicker' => 'Architecture map', 'blog_arch_title' => 'The homelab, end to end', - 'blog_arch_intro' => 'The current delivery path starts with a push to Gitea, runs local validation, builds arm64 images, syncs the validated commit into the GitOps mirror, and lets Argo CD reconcile the Kubernetes workloads. The infrastructure path stays manual through lab.sh, including the PXE/Pimox template builder, while the OCI edge routes public traffic back through the private path.', - 'blog_arch_caption' => 'The diagram is intentionally operational: it shows the app delivery loop, image flow, provisioning path, storage boundary, and public traffic path without hiding the practical bits that make a small lab behave like a platform.', + 'blog_arch_intro' => 'The current delivery path starts with a push to Gitea, runs local validation, builds arm64 images, syncs the validated commit into the GitOps mirror, and lets Argo CD reconcile the Kubernetes workloads. The infrastructure path stays manual through lab.sh, including the PXE/Pimox template builder, NVMe-backed worker clones, and the opt-in OpenWrt firewall VM, while the OCI edge routes public traffic back through the private path.', + 'blog_arch_caption' => 'The diagram is intentionally operational: it shows the app delivery loop, image flow, provisioning path, storage boundary, monitoring layer, OpenWrt firewall option, and public traffic path without hiding the practical bits that make a small lab behave like a platform.', 'blog_arch_fun_link' => 'Open the Christmas-tree version', 'blog_activity_kicker' => 'Recent activity log', 'blog_activity_title' => 'What changed since the first build', - 'blog_activity_intro' => 'The lab moved from a working Kubernetes experiment into a more complete self-hosted delivery system. The latest work focused on trust, repeatability, and making deploys match the exact commit that passed validation.', + 'blog_activity_intro' => 'The lab moved from a working Kubernetes experiment into a more complete self-hosted delivery system. The latest work focused on trust, repeatability, VM-based expansion, and making deploys match the exact commit that passed validation.', 'blog_activity_1' => 'Brought Gitea online as the local Git service, including persistent storage and the public /git/ route through the edge stack.', 'blog_activity_2' => 'Installed and validated a Debian-hosted Gitea Actions runner so pushes to main can build, scan, and deploy without depending on a laptop session.', 'blog_activity_3' => 'Added a custom checkout flow for the /git/ subpath and kept a persistent Debian checkout for the deployment scripts.', @@ -105,6 +112,10 @@ return [ 'blog_activity_7' => 'Split the demos into a dedicated demos-static image and Argo CD application so the PHP website stays small and boring.', 'blog_activity_8' => 'Fixed Gitea operational details around probes, service paths, backup dumps, and the user context used for safe backup execution.', 'blog_activity_9' => 'Validated the full main-branch deployment path: fetch main, apply OpenTofu layers, build and push arm64 images, refresh Argo CD, and confirm the runner completes successfully.', + 'blog_activity_10' => 'Built the Debian 13 arm64 Pimox template end to end with PXE, preseed, qemu-guest-agent discovery, cgroup validation, swap disabled, and a final seal step.', + 'blog_activity_11' => 'Added NVMe-backed Pimox worker clone automation so VM 9000 stays on local storage while worker nodes are created on nvme_thin_pool.', + 'blog_activity_12' => 'Added an opt-in OpenWrt VM path for a simple firewall between vmbr0 and vmbr1, with guardrails that avoid Orange Pi host networking changes.', + 'blog_activity_13' => 'Installed the monitoring stack with Grafana, Prometheus, Mimir, Loki, Promtail, node-exporter, and kube-state-metrics.', 'blog_todo_kicker' => 'Improvement backlog', 'blog_todo_title' => 'Todo list for the next homelab pass', 'blog_todo_intro' => 'These are improvement proposals, not chores for the sake of chores. Each item either reduces rebuild risk, tightens supply-chain hygiene, or makes the platform easier to operate when something fails.', @@ -115,11 +126,14 @@ return [ 'blog_todo_5' => 'Generate SBOMs and sign images so the local registry can prove what it is serving.', 'blog_todo_6' => 'Add Renovate or Dependabot-style dependency updates for base images, Helm charts, and GitHub/Gitea Actions.', 'blog_todo_7' => 'Enforce baseline Kubernetes policy with Kyverno or Gatekeeper: non-root, read-only roots, resource requests, and allowed registries.', - 'blog_todo_8' => 'Install observability that fits the hardware: Prometheus, Grafana, Loki, node-exporter, and a few high-signal alerts.', + 'blog_todo_8' => 'Turn the installed observability stack into useful operations views: a few high-signal dashboards, alerts for node health, storage pressure, certificate expiry, and failed app syncs.', 'blog_todo_9' => 'Schedule backup restore drills for Gitea and OpenEBS volumes, then write the exact restore runbook.', 'blog_todo_10' => 'Tighten TLS, SSH, and token rotation around the OCI edge, Gitea, registry, and runner credentials.', - 'blog_todo_11' => 'Design the next storage step before adding more apps: NAS, replicated storage, or a clearly documented single-node tradeoff.', + 'blog_todo_11' => 'Document the new storage split: local for the Pimox template, nvme_thin_pool for VM workers, OpenEBS for Kubernetes app data, and backup targets for anything that must survive a rebuild.', 'blog_todo_12' => 'Move sensitive app configuration into Sealed Secrets, External Secrets, or another explicit secret-management path.', + 'blog_todo_13' => 'After the new disk has breathing room, clone the first Pimox worker from VM 9000, join it with kubeadm, and verify labels, taints, CNI, storage, and workload scheduling.', + 'blog_todo_14' => 'Test the OpenWrt VM in a maintenance window before making it a gateway: confirm WAN, LAN, rollback access, DHCP settings, and that Pimox remains reachable.', + 'blog_todo_15' => 'Buy or configure a managed switch before VLAN work. Until then, keep OpenWrt as a simple two-interface firewall and avoid risky remote bridge rewrites.', 'blog_ideas_kicker' => 'Visitor ideas', 'blog_ideas_title' => 'What would you improve next?', 'blog_ideas_intro' => 'Send a practical idea for the homelab backlog. Submissions are stored as plain text, limited in size, and rendered escaped.', diff --git a/apps/website/lang/nah.php b/apps/website/lang/nah.php index 33bd602..8aa5d7b 100644 --- a/apps/website/lang/nah.php +++ b/apps/website/lang/nah.php @@ -59,13 +59,13 @@ return [ 'blog_kicker' => 'Homelab tlahcuilolli', 'blog_title' => 'Tlatecpanaliztli homelab CI/CD pipeline', - 'blog_subtitle' => 'Ce tlahtolli in quenin Debian server, Raspberry Pi, Orange Pi 5 Plus ipan Pimox, ihuan OCI edge box mochihua ce Kubernetes tlatequipanoliztli.', + 'blog_subtitle' => 'Ce tlahtolli in quenin Debian server, Raspberry Pi, Orange Pi 5 Plus ipan Pimox, OCI edge box, Debian 13 VM template, ihuan OpenWrt firewall plan mochihua ce Kubernetes tlatequipanoliztli.', 'blog_speaker_question' => 'Nehuatl mostla', 'blog_speaker_answer' => 'Nehuatl axcan', 'blog_q1' => 'Tleica niquichihua inin ihuan ahmo zan container tlatequipanoa?', 'blog_a1' => 'Ahmo zan website. Niquinequi nicnemiliz in operating model: infrastructure, Git, automation, recovery, ihuan reproducible rebuild.', 'blog_q2' => 'Tleica kubeadm ihuan ahmo managed Kubernetes?', - 'blog_a2' => 'kubeadm quipia cluster nechca metal. Debian quipia control plane, Raspberry Pi mochihua arm64 worker, ihuan Pimox ipan Orange Pi 5 Plus quimaca Debian 13 arm64 VM workers. Ipan inin niquita networking, storage, runtime, certificates, ihuan node recovery.', + 'blog_a2' => 'kubeadm quipia cluster nechca metal. Debian quipia control plane, Raspberry Pi mochihua arm64 worker, ihuan Pimox ipan Orange Pi 5 Plus quimaca repeatable Debian 13 arm64 VM workers. Ipan inin niquita networking, storage, runtime, certificates, ihuan node recovery.', 'blog_q3' => 'Canin nemi CI/CD ipan inin setup?', 'blog_a3' => 'Pipeline achi tepiton. OpenTofu quichihua cluster, platform, apps, ihuan edge. Argo CD quitta Git repo ihuan quichihua sync. Docker Buildx quichihua PHP website image para linux/arm64 ihuan quipush ipan local registry.', 'blog_q4' => 'Tleica private registry ihuan Gitea ipan lab?', @@ -77,10 +77,14 @@ return [ 'blog_q7' => 'Cluster huel quipias nochi demos?', 'blog_a7' => 'Quena, pampa demos cateh local-first ihuan separate static artifact. Website pod zan shell, demos-static pod quimaca bundles, browser quichihua tequitl. Real ONNX, Transformers.js, o video transcoding monequi lazy-load o occe node hueyi.', 'blog_q8' => 'Axcan lab huel quichihua worker nodes?', - 'blog_a8' => 'Quena, achi. Debian quipia provisioning layer: dnsmasq, nginx, PXE, GRUB, ihuan Debian 13 arm64 preseed. OpenTofu notza Pimox ika qm, quichihua VM 9000, quiboota network, quinstala OS, quichihua golden-node prep, quitzacua swap, quitta cgroups, quinstala containerd ihuan kubeadm tools, ihuan quicuepa template. Axcan monequi occe disk para clones.', + 'blog_a8' => 'Quena. Debian quipia provisioning layer: dnsmasq, nginx, PXE, GRUB, ihuan Debian 13 arm64 preseed. OpenTofu notza Pimox ika qm, quichihua VM 9000 ipan local storage, quiboota network, quinstala OS, quichihua golden-node prep, quitzacua swap, quitta cgroups, quinstala containerd ihuan kubeadm tools, ihuan quicuepa template. Worker clones yahui ipan nvme_thin_pool.', + 'blog_q9' => 'Ihuan OpenWrt no quiza nican?', + 'blog_a9' => 'Zan simple firewall. Pipeline huel quichihua OpenWrt ARM SystemReady VM, quipia vmbr0 quen WAN ihuan vmbr1 quen LAN, ihuan amo quipatla Orange Pi host networking. DHCP optional, VLANs mostla quema onca managed switch ihuan local test.', + 'blog_q10' => 'Tlein mopatla ipan observability?', + 'blog_a10' => 'Monitoring axcan nemi: Prometheus, Grafana, Loki, Mimir, Promtail, node-exporter, ihuan kube-state-metrics. Oc monequi achi cuali dashboards ihuan alerts.', 'blog_stack_title' => 'Tlamantli ihuan tleica nemi nican', 'blog_stack_1' => 'Debian Linux quimaca control-plane host, deployment workstation, PXE/preseed server, ihuan canin nemi OpenTofu, Docker, kubeadm, ihuan scripts.', - 'blog_stack_2' => 'Raspberry Pi quimaca axcan arm64 worker; Pimox ipan Orange Pi 5 Plus quimaca VM expansion path quema onca achi disk.', + 'blog_stack_2' => 'Raspberry Pi quimaca axcan arm64 worker; Pimox ipan Orange Pi 5 Plus quimaca VM expansion path. Template mocahua ipan local storage ihuan worker clones yahui ipan nvme_thin_pool.', 'blog_stack_3' => 'OpenTofu quichihua cluster, platform, apps, edge, ihuan provisioning configuration reproducible.', 'blog_stack_4' => 'Calico quimati pod networking; OpenEBS hostpath storage quipia data ipan cluster rebuilds.', 'blog_stack_5' => 'Argo CD quimaca GitOps control loop: manifests cateh ipan Git ihuan cluster moyecpana.', @@ -90,8 +94,11 @@ return [ 'blog_stack_9' => 'Yancuic demos quipia network jitter graphs, local JSON/JWT/log tools, architecture simulator, offline traveler converter, redactor, sentiment analysis, ihuan model drift simulation.', 'blog_stack_10' => 'ML demos monequi client-side Wasm/ONNX/Transformers.js, ahmo server-side jobs.', 'blog_stack_11' => 'Demo code axcan quichihua demos-static image ihuan Argo CD app, exposed ipan /demo-apps/. PHP website zan catalog.', - 'blog_stack_12' => 'Pimox worker pipeline quichihua qm ika SSH para OVMF/virtio-scsi Debian 13 arm64 VM, quichia qemu-guest-agent, quiseala, ihuan quicuepa VM 9000 template.', + 'blog_stack_12' => 'Pimox worker pipeline quichihua qm ika SSH para OVMF/virtio-scsi Debian 13 arm64 VM, quichia qemu-guest-agent, quiseala, ihuan quicuepa VM 9000 template ipan local storage.', 'blog_stack_13' => 'Golden image quipia Kubernetes prereqs: swap disabled, cgroup boot options checked, kernel modules, containerd systemd cgroups, kubeadm/kubelet/kubectl, ihuan qemu-guest-agent.', + 'blog_stack_14' => 'Worker clone automation count-based ihuan idempotent: LAB_PIMOX_WORKER_COUNT=1 quinequi VM 9010 ma onca, ahmo yancuic VM nochipa. Local storage amo quiselia worker clones.', + 'blog_stack_15' => 'OpenWrt amo quiza ipan Debian golden-node template. Lab quitemoa ARM SystemReady EFI image, quimporta VM 9050 ipan nvme_thin_pool, ihuan zan quisa quema LAB_OPENWRT_VM=true.', + 'blog_stack_16' => 'Monitoring layer quipia Prometheus Stack, Grafana, Mimir, Loki, Promtail, node-exporter, ihuan kube-state-metrics.', 'demos_kicker' => 'Tepiton tools ipan browser', 'demos_title' => 'Demo Apps',