Update homelab blog with Pimox provisioning
This commit is contained in:
parent
6cf83bb682
commit
4baad45305
|
|
@ -41,6 +41,8 @@ $stackKeys = [
|
||||||
'blog_stack_9',
|
'blog_stack_9',
|
||||||
'blog_stack_10',
|
'blog_stack_10',
|
||||||
'blog_stack_11',
|
'blog_stack_11',
|
||||||
|
'blog_stack_12',
|
||||||
|
'blog_stack_13',
|
||||||
];
|
];
|
||||||
|
|
||||||
$treeHref = 'homelab-tree.php?lang=' . urlencode($lang);
|
$treeHref = 'homelab-tree.php?lang=' . urlencode($lang);
|
||||||
|
|
@ -51,15 +53,18 @@ $stackSourceLinks = [
|
||||||
'blog_stack_1' => [
|
'blog_stack_1' => [
|
||||||
['label' => 'lab.sh', 'path' => 'lab.sh'],
|
['label' => 'lab.sh', 'path' => 'lab.sh'],
|
||||||
['label' => 'cluster/main.tf', 'path' => 'bootstrap/cluster/main.tf'],
|
['label' => 'cluster/main.tf', 'path' => 'bootstrap/cluster/main.tf'],
|
||||||
|
['label' => 'provisioning/main.tf', 'path' => 'bootstrap/provisioning/main.tf'],
|
||||||
],
|
],
|
||||||
'blog_stack_2' => [
|
'blog_stack_2' => [
|
||||||
['label' => 'cluster/main.tf', 'path' => 'bootstrap/cluster/main.tf'],
|
['label' => 'cluster/main.tf', 'path' => 'bootstrap/cluster/main.tf'],
|
||||||
|
['label' => 'provisioning/main.tf', 'path' => 'bootstrap/provisioning/main.tf'],
|
||||||
],
|
],
|
||||||
'blog_stack_3' => [
|
'blog_stack_3' => [
|
||||||
['label' => 'lab.sh', 'path' => 'lab.sh'],
|
['label' => 'lab.sh', 'path' => 'lab.sh'],
|
||||||
['label' => 'cluster', 'path' => 'bootstrap/cluster/main.tf'],
|
['label' => 'cluster', 'path' => 'bootstrap/cluster/main.tf'],
|
||||||
['label' => 'platform', 'path' => 'bootstrap/platform/main.tf'],
|
['label' => 'platform', 'path' => 'bootstrap/platform/main.tf'],
|
||||||
['label' => 'apps', 'path' => 'bootstrap/apps/main.tf'],
|
['label' => 'apps', 'path' => 'bootstrap/apps/main.tf'],
|
||||||
|
['label' => 'provisioning', 'path' => 'bootstrap/provisioning/main.tf'],
|
||||||
['label' => 'edge', 'path' => 'bootstrap/edge/main.tf'],
|
['label' => 'edge', 'path' => 'bootstrap/edge/main.tf'],
|
||||||
],
|
],
|
||||||
'blog_stack_4' => [
|
'blog_stack_4' => [
|
||||||
|
|
@ -98,6 +103,15 @@ $stackSourceLinks = [
|
||||||
['label' => 'demos web-app.yaml', 'path' => 'apps/demos-static/web-app.yaml'],
|
['label' => 'demos web-app.yaml', 'path' => 'apps/demos-static/web-app.yaml'],
|
||||||
['label' => 'website demos.php', 'path' => 'apps/website/demos.php'],
|
['label' => 'website demos.php', 'path' => 'apps/website/demos.php'],
|
||||||
],
|
],
|
||||||
|
'blog_stack_12' => [
|
||||||
|
['label' => 'provisioning/main.tf', 'path' => 'bootstrap/provisioning/main.tf'],
|
||||||
|
['label' => 'lab.sh Pimox pipeline', 'path' => 'lab.sh'],
|
||||||
|
],
|
||||||
|
'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'],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $sourceBase): void {
|
function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $sourceBase): void {
|
||||||
|
|
@ -188,93 +202,101 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="diagram-shell" aria-label="Professional homelab architecture diagram">
|
<div class="diagram-shell" aria-label="Professional homelab architecture diagram">
|
||||||
<svg class="homelab-map" viewBox="0 0 1120 720" role="img" aria-labelledby="homelab-map-title homelab-map-desc">
|
<svg class="homelab-map" viewBox="0 0 1120 820" role="img" aria-labelledby="homelab-map-title homelab-map-desc">
|
||||||
<title id="homelab-map-title">Homelab architecture map</title>
|
<title id="homelab-map-title">Homelab architecture map</title>
|
||||||
<desc id="homelab-map-desc">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.</desc>
|
<desc id="homelab-map-desc">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.</desc>
|
||||||
<defs>
|
<defs>
|
||||||
<marker id="map-arrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto">
|
<marker id="map-arrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto">
|
||||||
<path d="M2,2 L10,6 L2,10 Z" fill="#2b6cb0"></path>
|
<path d="M2,2 L10,6 L2,10 Z" fill="#2b6cb0"></path>
|
||||||
</marker>
|
</marker>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<rect class="diagram-zone diagram-zone-source" x="24" y="40" width="310" height="640" rx="12"></rect>
|
<rect class="diagram-zone diagram-zone-source" x="24" y="40" width="310" height="740" rx="12"></rect>
|
||||||
<text class="diagram-zone-title" x="46" y="74">Source, validation, and images</text>
|
<text class="diagram-zone-title" x="46" y="74">Source, validation, and images</text>
|
||||||
|
|
||||||
<rect class="diagram-zone diagram-zone-platform" x="382" y="40" width="340" height="640" rx="12"></rect>
|
<rect class="diagram-zone diagram-zone-platform" x="382" y="40" width="340" height="740" rx="12"></rect>
|
||||||
<text class="diagram-zone-title" x="404" y="74">Debian node 192.168.100.68</text>
|
<text class="diagram-zone-title" x="404" y="74">Debian node 192.168.100.68</text>
|
||||||
|
|
||||||
<rect class="diagram-zone diagram-zone-runtime" x="770" y="40" width="326" height="640" rx="12"></rect>
|
<rect class="diagram-zone diagram-zone-runtime" x="770" y="40" width="326" height="740" rx="12"></rect>
|
||||||
<text class="diagram-zone-title" x="792" y="74">Edge access and workloads</text>
|
<text class="diagram-zone-title" x="792" y="74">Edge access and workloads</text>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-blue" transform="translate(54 110)">
|
<g class="diagram-node node-accent-blue" transform="translate(54 100)">
|
||||||
<rect width="240" height="74" rx="8"></rect>
|
<rect width="240" height="74" rx="8"></rect>
|
||||||
<text x="18" y="28">Developer laptop</text>
|
<text x="18" y="28">Developer laptop</text>
|
||||||
<text class="diagram-small" x="18" y="52">edit, test, push main</text>
|
<text class="diagram-small" x="18" y="52">edit, test, push main</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-blue" transform="translate(54 218)">
|
<g class="diagram-node node-accent-blue" transform="translate(54 208)">
|
||||||
<rect width="240" height="82" rx="8"></rect>
|
<rect width="240" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Gitea repository</text>
|
<text x="18" y="27">Gitea repository</text>
|
||||||
<text class="diagram-small" x="18" y="50">https://lab2025.duckdns.org/git/</text>
|
<text class="diagram-small" x="18" y="50">https://lab2025.duckdns.org/git/</text>
|
||||||
<text class="diagram-small" x="18" y="68">main is the release branch</text>
|
<text class="diagram-small" x="18" y="68">main is the release branch</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-teal" transform="translate(54 338)">
|
<g class="diagram-node node-accent-teal" transform="translate(54 318)">
|
||||||
<rect width="240" height="82" rx="8"></rect>
|
<rect width="240" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Gitea Actions runner</text>
|
<text x="18" y="27">Gitea Actions runner</text>
|
||||||
<text class="diagram-small" x="18" y="50">Debian hosted runner</text>
|
<text class="diagram-small" x="18" y="50">Debian hosted runner</text>
|
||||||
<text class="diagram-small" x="18" y="68">custom checkout for /git/ path</text>
|
<text class="diagram-small" x="18" y="68">runs app-only deploys</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-red" transform="translate(54 458)">
|
<g class="diagram-node node-accent-red" transform="translate(54 430)">
|
||||||
<rect width="240" height="82" rx="8"></rect>
|
<rect width="240" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Validation gates</text>
|
<text x="18" y="27">Validation gates</text>
|
||||||
<text class="diagram-small" x="18" y="50">Gitleaks secret scan</text>
|
<text class="diagram-small" x="18" y="50">Gitleaks secret scan</text>
|
||||||
<text class="diagram-small" x="18" y="68">Trivy IaC and image posture</text>
|
<text class="diagram-small" x="18" y="68">Trivy IaC and image posture</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-green" transform="translate(54 578)">
|
<g class="diagram-node node-accent-green" transform="translate(54 542)">
|
||||||
<rect width="240" height="70" rx="8"></rect>
|
<rect width="240" height="70" rx="8"></rect>
|
||||||
<text x="18" y="27">Buildx image build</text>
|
<text x="18" y="27">Buildx image build</text>
|
||||||
<text class="diagram-small" x="18" y="50">linux/arm64 website + demos</text>
|
<text class="diagram-small" x="18" y="50">linux/arm64 website + demos</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-purple" transform="translate(412 108)">
|
<g class="diagram-node node-accent-purple" transform="translate(412 92)">
|
||||||
<rect width="280" height="82" rx="8"></rect>
|
<rect width="280" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">OpenTofu + lab.sh</text>
|
<text x="18" y="27">OpenTofu + lab.sh</text>
|
||||||
<text class="diagram-small" x="18" y="50">infra, platform, apps, edge</text>
|
<text class="diagram-small" x="18" y="50">manual infra apply path</text>
|
||||||
<text class="diagram-small" x="18" y="68">repeatable apply path</text>
|
<text class="diagram-small" x="18" y="68">apps command for CI deploys</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-blue" transform="translate(412 222)">
|
<g class="diagram-node node-accent-orange" transform="translate(412 202)">
|
||||||
|
<rect width="280" height="96" rx="8"></rect>
|
||||||
|
<text x="18" y="28">PXE + preseed service</text>
|
||||||
|
<text class="diagram-small" x="18" y="52">dnsmasq TFTP, nginx HTTP</text>
|
||||||
|
<text class="diagram-small" x="18" y="70">Debian 13 arm64 netboot</text>
|
||||||
|
<text class="diagram-small" x="18" y="88">golden-node prep scripts</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g class="diagram-node node-accent-blue" transform="translate(412 326)">
|
||||||
<rect width="280" height="82" rx="8"></rect>
|
<rect width="280" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">kubeadm control plane</text>
|
<text x="18" y="27">kubeadm control plane</text>
|
||||||
<text class="diagram-small" x="18" y="50">API server, scheduler, controller</text>
|
<text class="diagram-small" x="18" y="50">API server, scheduler, controller</text>
|
||||||
<text class="diagram-small" x="18" y="68">Calico pod networking</text>
|
<text class="diagram-small" x="18" y="68">Calico pod networking</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-teal" transform="translate(412 336)">
|
<g class="diagram-node node-accent-teal" transform="translate(412 438)">
|
||||||
<rect width="280" height="82" rx="8"></rect>
|
<rect width="280" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">GitOps mirror</text>
|
<text x="18" y="27">GitOps mirror</text>
|
||||||
<text class="diagram-small" x="18" y="50">validated commit copied locally</text>
|
<text class="diagram-small" x="18" y="50">validated commit copied locally</text>
|
||||||
<text class="diagram-small" x="18" y="68">Argo CD reads deploy state</text>
|
<text class="diagram-small" x="18" y="68">Argo CD reads deploy state</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-green" transform="translate(412 450)">
|
<g class="diagram-node node-accent-green" transform="translate(412 550)">
|
||||||
<rect width="280" height="82" rx="8"></rect>
|
<rect width="280" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Argo CD</text>
|
<text x="18" y="27">Argo CD</text>
|
||||||
<text class="diagram-small" x="18" y="50">container-registry, website</text>
|
<text class="diagram-small" x="18" y="50">container-registry, website</text>
|
||||||
<text class="diagram-small" x="18" y="68">gitea and demos-static apps</text>
|
<text class="diagram-small" x="18" y="68">gitea and demos-static apps</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-orange" transform="translate(412 564)">
|
<g class="diagram-node node-accent-orange" transform="translate(412 662)">
|
||||||
<rect width="280" height="82" rx="8"></rect>
|
<rect width="280" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Storage and backups</text>
|
<text x="18" y="27">Storage and backups</text>
|
||||||
<text class="diagram-small" x="18" y="50">OpenEBS retained hostpath PVs</text>
|
<text class="diagram-small" x="18" y="50">OpenEBS retained hostpath PVs</text>
|
||||||
<text class="diagram-small" x="18" y="68">Gitea dumps and external SSD</text>
|
<text class="diagram-small" x="18" y="68">Gitea dumps and external SSD</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-blue" transform="translate(800 106)">
|
<g class="diagram-node node-accent-blue" transform="translate(800 92)">
|
||||||
<rect width="258" height="96" rx="8"></rect>
|
<rect width="258" height="96" rx="8"></rect>
|
||||||
<text x="18" y="28">OCI edge host</text>
|
<text x="18" y="28">OCI edge host</text>
|
||||||
<text class="diagram-small" x="18" y="52">nginx, HAProxy, Varnish, Squid</text>
|
<text class="diagram-small" x="18" y="52">nginx, HAProxy, Varnish, Squid</text>
|
||||||
|
|
@ -282,14 +304,14 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
||||||
<text class="diagram-small" x="18" y="88">public DNS entry point</text>
|
<text class="diagram-small" x="18" y="88">public DNS entry point</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-purple" transform="translate(800 246)">
|
<g class="diagram-node node-accent-purple" transform="translate(800 218)">
|
||||||
<rect width="258" height="82" rx="8"></rect>
|
<rect width="258" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Tailscale + NodePorts</text>
|
<text x="18" y="27">Tailscale + NodePorts</text>
|
||||||
<text class="diagram-small" x="18" y="50">30080 website, 30081 demos</text>
|
<text class="diagram-small" x="18" y="50">30080 website, 30081 demos</text>
|
||||||
<text class="diagram-small" x="18" y="68">30300 Gitea service path</text>
|
<text class="diagram-small" x="18" y="68">30300 Gitea service path</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-green" transform="translate(800 366)">
|
<g class="diagram-node node-accent-green" transform="translate(800 330)">
|
||||||
<rect width="258" height="96" rx="8"></rect>
|
<rect width="258" height="96" rx="8"></rect>
|
||||||
<text x="18" y="28">Raspberry Pi 192.168.100.89</text>
|
<text x="18" y="28">Raspberry Pi 192.168.100.89</text>
|
||||||
<text class="diagram-small" x="18" y="52">arm64 Kubernetes worker</text>
|
<text class="diagram-small" x="18" y="52">arm64 Kubernetes worker</text>
|
||||||
|
|
@ -297,38 +319,52 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
||||||
<text class="diagram-small" x="18" y="88">demos-static and lab apps</text>
|
<text class="diagram-small" x="18" y="88">demos-static and lab apps</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<g class="diagram-node node-accent-teal" transform="translate(800 506)">
|
<g class="diagram-node node-accent-red" transform="translate(800 466)">
|
||||||
|
<rect width="258" height="112" rx="8"></rect>
|
||||||
|
<text x="18" y="28">Orange Pi 5 Plus Pimox</text>
|
||||||
|
<text class="diagram-small" x="18" y="52">VM 9000 Debian template</text>
|
||||||
|
<text class="diagram-small" x="18" y="70">OVMF, virtio-scsi, qemu agent</text>
|
||||||
|
<text class="diagram-small" x="18" y="88">future worker clones</text>
|
||||||
|
<text class="diagram-small" x="18" y="106">waiting on more disk</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g class="diagram-node node-accent-teal" transform="translate(800 616)">
|
||||||
<rect width="258" height="82" rx="8"></rect>
|
<rect width="258" height="82" rx="8"></rect>
|
||||||
<text x="18" y="27">Local registry :30500</text>
|
<text x="18" y="27">Local registry :30500</text>
|
||||||
<text class="diagram-small" x="18" y="50">php-website and demos-static</text>
|
<text class="diagram-small" x="18" y="50">php-website and demos-static</text>
|
||||||
<text class="diagram-small" x="18" y="68">pulled by arm64 workloads</text>
|
<text class="diagram-small" x="18" y="68">pulled by arm64 workloads</text>
|
||||||
</g>
|
</g>
|
||||||
|
|
||||||
<path class="diagram-link" d="M174 184 L174 218"></path>
|
<path class="diagram-link" d="M174 174 L174 208"></path>
|
||||||
<path class="diagram-link" d="M174 300 L174 338"></path>
|
<path class="diagram-link" d="M174 290 L174 318"></path>
|
||||||
<path class="diagram-link" d="M174 420 L174 458"></path>
|
<path class="diagram-link" d="M174 400 L174 430"></path>
|
||||||
<path class="diagram-link" d="M174 540 L174 578"></path>
|
<path class="diagram-link" d="M174 512 L174 542"></path>
|
||||||
<path class="diagram-link" d="M294 616 C346 616 352 149 412 149"></path>
|
<path class="diagram-link" d="M294 577 C346 577 352 133 412 133"></path>
|
||||||
<path class="diagram-link" d="M294 616 C372 616 722 560 800 547"></path>
|
<path class="diagram-link" d="M294 577 C372 577 722 657 800 657"></path>
|
||||||
<path class="diagram-link" d="M294 379 C340 379 360 149 412 149"></path>
|
<path class="diagram-link" d="M294 359 C340 359 360 133 412 133"></path>
|
||||||
<path class="diagram-link" d="M294 259 C348 259 360 377 412 377"></path>
|
<path class="diagram-link" d="M294 249 C348 249 360 479 412 479"></path>
|
||||||
<path class="diagram-link" d="M552 304 L552 336"></path>
|
<path class="diagram-link" d="M552 174 L552 202"></path>
|
||||||
<path class="diagram-link" d="M552 418 L552 450"></path>
|
<path class="diagram-link" d="M552 298 L552 326"></path>
|
||||||
<path class="diagram-link" d="M692 491 C748 491 744 414 800 414"></path>
|
<path class="diagram-link" d="M552 520 L552 550"></path>
|
||||||
<path class="diagram-link" d="M929 202 L929 246"></path>
|
<path class="diagram-link" d="M692 250 C746 250 746 522 800 522"></path>
|
||||||
<path class="diagram-link" d="M929 328 L929 366"></path>
|
<path class="diagram-link" d="M692 591 C748 591 744 378 800 378"></path>
|
||||||
<path class="diagram-link" d="M929 506 L929 462"></path>
|
<path class="diagram-link" d="M929 188 L929 218"></path>
|
||||||
|
<path class="diagram-link" d="M929 300 L929 330"></path>
|
||||||
|
<path class="diagram-link" d="M929 616 L929 426"></path>
|
||||||
|
|
||||||
<text class="diagram-link-label" x="184" y="205">push</text>
|
<text class="diagram-link-label" x="184" y="198">push</text>
|
||||||
<text class="diagram-link-label" x="196" y="327">workflow</text>
|
<text class="diagram-link-label" x="196" y="312">workflow</text>
|
||||||
<text class="diagram-link-label" x="200" y="448">scan</text>
|
<text class="diagram-link-label" x="200" y="424">scan</text>
|
||||||
<text class="diagram-link-label" x="205" y="568">build</text>
|
<text class="diagram-link-label" x="205" y="536">build</text>
|
||||||
<text class="diagram-link-label" x="320" y="124">apply</text>
|
<text class="diagram-link-label" x="320" y="124">manual infra</text>
|
||||||
<text class="diagram-link-label" x="346" y="346">validated Git</text>
|
<text class="diagram-link-label" x="344" y="386">validated Git</text>
|
||||||
<text class="diagram-link-label" x="710" y="462">sync apps</text>
|
<text class="diagram-link-label" x="562" y="195">serve boot</text>
|
||||||
<text class="diagram-link-label" x="934" y="232">secure tunnel</text>
|
<text class="diagram-link-label" x="566" y="320">join path</text>
|
||||||
<text class="diagram-link-label" x="934" y="352">service traffic</text>
|
<text class="diagram-link-label" x="710" y="494">Pimox template</text>
|
||||||
<text class="diagram-link-label" x="946" y="492">image pulls</text>
|
<text class="diagram-link-label" x="710" y="420">sync apps</text>
|
||||||
|
<text class="diagram-link-label" x="934" y="212">secure tunnel</text>
|
||||||
|
<text class="diagram-link-label" x="934" y="322">service traffic</text>
|
||||||
|
<text class="diagram-link-label" x="946" y="604">image pulls</text>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -514,6 +550,30 @@ function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $so
|
||||||
<?php echo $text['blog_a7']; ?>
|
<?php echo $text['blog_a7']; ?>
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="message question">
|
||||||
|
<div class="speaker"
|
||||||
|
data-translate data-key="blog_speaker_question"
|
||||||
|
data-en="<?php echo htmlspecialchars($en['blog_speaker_question']); ?>">
|
||||||
|
<?php echo $text['blog_speaker_question']; ?>
|
||||||
|
</div>
|
||||||
|
<p data-translate data-key="blog_q8"
|
||||||
|
data-en="<?php echo htmlspecialchars($en['blog_q8']); ?>">
|
||||||
|
<?php echo $text['blog_q8']; ?>
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="message answer">
|
||||||
|
<div class="speaker"
|
||||||
|
data-translate data-key="blog_speaker_answer"
|
||||||
|
data-en="<?php echo htmlspecialchars($en['blog_speaker_answer']); ?>">
|
||||||
|
<?php echo $text['blog_speaker_answer']; ?>
|
||||||
|
</div>
|
||||||
|
<p data-translate data-key="blog_a8"
|
||||||
|
data-en="<?php echo htmlspecialchars($en['blog_a8']); ?>">
|
||||||
|
<?php echo $text['blog_a8']; ?>
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="activity-log" aria-labelledby="activity-log-title">
|
<section class="activity-log" aria-labelledby="activity-log-title">
|
||||||
|
|
|
||||||
|
|
@ -55,13 +55,13 @@ return [
|
||||||
|
|
||||||
'blog_kicker' => 'Homelab field notes',
|
'blog_kicker' => 'Homelab field notes',
|
||||||
'blog_title' => 'I accidentally built a tiny CI/CD platform',
|
'blog_title' => 'I accidentally built a tiny CI/CD platform',
|
||||||
'blog_subtitle' => 'A casual conversation about how a Debian box, a Raspberry Pi, 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, and a suspicious amount of stubbornness became a repeatable Kubernetes delivery path.',
|
||||||
'blog_speaker_question' => 'Future me, judging',
|
'blog_speaker_question' => 'Future me, judging',
|
||||||
'blog_speaker_answer' => 'Me, holding coffee',
|
'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_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_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_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 suddenly networking, storage, container runtimes, certs, and node recovery are not mysterious cloud magic. They are my problem. Educational, in the same way stepping on a rake is educational.',
|
'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_q3' => 'So where is the CI/CD part hiding?',
|
'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_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?',
|
'blog_q4' => 'Why run your own registry and Gitea? Was the simple option unavailable?',
|
||||||
|
|
@ -72,10 +72,12 @@ return [
|
||||||
'blog_a6' => 'Correct. The CV now has an Elegant mode for terminal-green seriousness and a Fancy mode where my face follows the cursor like it has opinions. The Demos page is now a catalog that links to a separate demos-static artifact, because apparently the natural next step after building a platform is learning not to shove every toy into the same image.',
|
'blog_a6' => 'Correct. The CV now has an Elegant mode for terminal-green seriousness and a Fancy mode where my face follows the cursor like it has opinions. The Demos page is now a catalog that links to a separate demos-static artifact, because apparently the natural next step after building a platform is learning not to shove every toy into the same image.',
|
||||||
'blog_q7' => 'Can the current cluster actually handle all that, or are we about to smoke the Pi?',
|
'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_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_stack_title' => 'Technologies and why they are here',
|
'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, and the place where OpenTofu, Docker, kubeadm, and the scripts do their thing.',
|
'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 an arm64 worker, which is great for learning multi-architecture builds and for reminding me that CPU architecture is not a decorative detail.',
|
'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_3' => 'OpenTofu makes the cluster, platform, apps, and edge config repeatable, because "I swear I remember the command" is not a disaster recovery strategy.',
|
'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_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.',
|
'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.',
|
||||||
'blog_stack_6' => 'The OCI edge host runs nginx, HAProxy, Varnish, and Squid so TLS, routing, and caching stay outside the home network while Tailscale sneaks the traffic back to the worker node.',
|
'blog_stack_6' => 'The OCI edge host runs nginx, HAProxy, Varnish, and Squid so TLS, routing, and caching stay outside the home network while Tailscale sneaks the traffic back to the worker node.',
|
||||||
|
|
@ -84,10 +86,12 @@ 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_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_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_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_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_arch_kicker' => 'Architecture map',
|
'blog_arch_kicker' => 'Architecture map',
|
||||||
'blog_arch_title' => 'The homelab, end to end',
|
'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 while the OCI edge routes public traffic back through the private path.',
|
'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 control flow, image flow, storage boundary, and public traffic path without hiding the practical bits that make a small lab behave like a platform.',
|
'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_fun_link' => 'Open the Christmas-tree version',
|
'blog_arch_fun_link' => 'Open the Christmas-tree version',
|
||||||
'blog_activity_kicker' => 'Recent activity log',
|
'blog_activity_kicker' => 'Recent activity log',
|
||||||
'blog_activity_title' => 'What changed since the first build',
|
'blog_activity_title' => 'What changed since the first build',
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,13 @@ return [
|
||||||
|
|
||||||
'blog_kicker' => 'Homelab tlahcuilolli',
|
'blog_kicker' => 'Homelab tlahcuilolli',
|
||||||
'blog_title' => 'Tlatecpanaliztli homelab CI/CD pipeline',
|
'blog_title' => 'Tlatecpanaliztli homelab CI/CD pipeline',
|
||||||
'blog_subtitle' => 'Ce tlahtolli in quenin Debian server, Raspberry Pi, ihuan OCI edge box mochihua ce Kubernetes tlatequipanoliztli.',
|
'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_speaker_question' => 'Nehuatl mostla',
|
'blog_speaker_question' => 'Nehuatl mostla',
|
||||||
'blog_speaker_answer' => 'Nehuatl axcan',
|
'blog_speaker_answer' => 'Nehuatl axcan',
|
||||||
'blog_q1' => 'Tleica niquichihua inin ihuan ahmo zan container tlatequipanoa?',
|
'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_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_q2' => 'Tleica kubeadm ihuan ahmo managed Kubernetes?',
|
||||||
'blog_a2' => 'kubeadm quipia cluster nechca metal. Debian quipia control plane ihuan Raspberry Pi mochihua arm64 worker, ic 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 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_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_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?',
|
'blog_q4' => 'Tleica private registry ihuan Gitea ipan lab?',
|
||||||
|
|
@ -76,10 +76,12 @@ return [
|
||||||
'blog_a6' => 'Quena. CV quipia Elegant mode para console green ihuan Fancy mode canin noxayac quitta cursor. Demos page axcan catalog ihuan demos-static artifact.',
|
'blog_a6' => 'Quena. CV quipia Elegant mode para console green ihuan Fancy mode canin noxayac quitta cursor. Demos page axcan catalog ihuan demos-static artifact.',
|
||||||
'blog_q7' => 'Cluster huel quipias nochi demos?',
|
'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_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_stack_title' => 'Tlamantli ihuan tleica nemi nican',
|
'blog_stack_title' => 'Tlamantli ihuan tleica nemi nican',
|
||||||
'blog_stack_1' => 'Debian Linux quimaca stable control-plane host ihuan canin nemi OpenTofu, Docker, kubeadm, ihuan scripts.',
|
'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 arm64 worker inic niyeyecoa multi-architecture builds ihuan node placement.',
|
'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_3' => 'OpenTofu quichihua cluster, platform, apps, ihuan edge configuration reproducible.',
|
'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_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.',
|
'blog_stack_5' => 'Argo CD quimaca GitOps control loop: manifests cateh ipan Git ihuan cluster moyecpana.',
|
||||||
'blog_stack_6' => 'OCI edge host quipia nginx, HAProxy, Varnish, ihuan Squid para TLS, routing, ihuan cache, ihuan Tailscale quihuica traffic ipan worker node.',
|
'blog_stack_6' => 'OCI edge host quipia nginx, HAProxy, Varnish, ihuan Squid para TLS, routing, ihuan cache, ihuan Tailscale quihuica traffic ipan worker node.',
|
||||||
|
|
@ -88,6 +90,8 @@ 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_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_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_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_13' => 'Golden image quipia Kubernetes prereqs: swap disabled, cgroup boot options checked, kernel modules, containerd systemd cgroups, kubeadm/kubelet/kubectl, ihuan qemu-guest-agent.',
|
||||||
|
|
||||||
'demos_kicker' => 'Tepiton tools ipan browser',
|
'demos_kicker' => 'Tepiton tools ipan browser',
|
||||||
'demos_title' => 'Demo Apps',
|
'demos_title' => 'Demo Apps',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue