[ ['label' => 'lab.sh', 'path' => 'lab.sh'], ['label' => 'cluster/main.tf', 'path' => 'bootstrap/cluster/main.tf'], ], 'blog_stack_2' => [ ['label' => 'cluster/main.tf', 'path' => 'bootstrap/cluster/main.tf'], ], 'blog_stack_3' => [ ['label' => 'lab.sh', 'path' => 'lab.sh'], ['label' => 'cluster', 'path' => 'bootstrap/cluster/main.tf'], ['label' => 'platform', 'path' => 'bootstrap/platform/main.tf'], ['label' => 'apps', 'path' => 'bootstrap/apps/main.tf'], ['label' => 'edge', 'path' => 'bootstrap/edge/main.tf'], ], 'blog_stack_4' => [ ['label' => 'platform/main.tf', 'path' => 'bootstrap/platform/main.tf'], ], 'blog_stack_5' => [ ['label' => 'apps/main.tf', 'path' => 'bootstrap/apps/main.tf'], ], 'blog_stack_6' => [ ['label' => 'edge/main.tf', 'path' => 'bootstrap/edge/main.tf'], ['label' => 'nginx template', 'path' => 'bootstrap/edge/templates/default.conf.tftpl'], ['label' => 'HAProxy template', 'path' => 'bootstrap/edge/templates/haproxy.cfg.tftpl'], ], 'blog_stack_7' => [ ['label' => 'cv-theme.js', 'path' => 'apps/website/cv-theme.js'], ['label' => 'cv.php', 'path' => 'apps/website/cv.php'], ['label' => 'styles.css', 'path' => 'apps/website/styles.css'], ], 'blog_stack_8' => [ ['label' => 'media-cruncher.js', 'path' => 'apps/demos-static/public/media-cruncher/media-cruncher.js'], ['label' => 'media-cruncher page', 'path' => 'apps/demos-static/public/media-cruncher/index.html'], ], 'blog_stack_9' => [ ['label' => 'demo catalog', 'path' => 'apps/demos-static/public/index.html'], ['label' => 'network-quality.js', 'path' => 'apps/demos-static/public/network-quality/network-quality.js'], ['label' => 'dev-toolbelt.js', 'path' => 'apps/demos-static/public/dev-toolbelt/dev-toolbelt.js'], ['label' => 'architecture-simulator.js', 'path' => 'apps/demos-static/public/architecture-simulator/architecture-simulator.js'], ], 'blog_stack_10' => [ ['label' => 'sentiment-sandbox.js', 'path' => 'apps/demos-static/public/sentiment-sandbox/sentiment-sandbox.js'], ['label' => 'model-drift.js', 'path' => 'apps/demos-static/public/model-drift/model-drift.js'], ['label' => 'privacy-redactor.js', 'path' => 'apps/demos-static/public/privacy-redactor/privacy-redactor.js'], ], 'blog_stack_11' => [ ['label' => 'demos Dockerfile', 'path' => 'apps/demos-static/Dockerfile'], ['label' => 'demos web-app.yaml', 'path' => 'apps/demos-static/web-app.yaml'], ['label' => 'website demos.php', 'path' => 'apps/website/demos.php'], ], ]; function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $sourceBase): void { if (!isset($sourceLinks[$stackKey])) { return; } echo ''; } ?> <?php echo $text['blog_title']; ?> - <?php echo $text['name']; ?>

Homelab architecture map Git push enters Gitea, Gitea Actions validates and builds images, OpenTofu manages the cluster, Argo CD syncs manifests, and the OCI edge routes traffic over Tailscale into Kubernetes services. Source, validation, and images Debian node 192.168.100.68 Edge access and workloads Developer laptop edit, test, push main Gitea repository https://lab2025.duckdns.org/git/ main is the release branch Gitea Actions runner Debian hosted runner custom checkout for /git/ path Validation gates Gitleaks secret scan Trivy IaC and image posture Buildx image build linux/arm64 website + demos OpenTofu + lab.sh infra, platform, apps, edge repeatable apply path kubeadm control plane API server, scheduler, controller Calico pod networking GitOps mirror validated commit copied locally Argo CD reads deploy state Argo CD container-registry, website gitea and demos-static apps Storage and backups OpenEBS retained hostpath PVs Gitea dumps and external SSD OCI edge host nginx, HAProxy, Varnish, Squid TLS, routing, caching public DNS entry point Tailscale + NodePorts 30080 website, 30081 demos 30300 Gitea service path Raspberry Pi 192.168.100.89 arm64 Kubernetes worker website-production pods demos-static and lab apps Local registry :30500 php-website and demos-static pulled by arm64 workloads push workflow scan build apply validated Git sync apps secure tunnel service traffic image pulls

    $activityKey): ?>