Document website performance tuning
This commit is contained in:
parent
cf6834b264
commit
a5fc43b78e
31
README.md
31
README.md
|
|
@ -19,10 +19,14 @@ The lab is intentionally small but production-shaped:
|
||||||
- Argo CD continuously reconciles Kubernetes manifests from this repo
|
- Argo CD continuously reconciles Kubernetes manifests from this repo
|
||||||
- a local registry stores the website and demos images built for the worker
|
- a local registry stores the website and demos images built for the worker
|
||||||
architecture
|
architecture
|
||||||
|
- the website image keeps Apache as the public server, uses PHP-FPM with
|
||||||
|
OPcache for dynamic endpoints, and pre-renders read-heavy pages to static
|
||||||
|
HTML during the image build
|
||||||
- SOPS with age is the committed secret-management path for future encrypted
|
- SOPS with age is the committed secret-management path for future encrypted
|
||||||
Kubernetes secrets
|
Kubernetes secrets
|
||||||
- an OCI jump box provides the public edge path back into the homelab over
|
- an OCI jump box provides the public edge path back into the homelab over
|
||||||
Tailscale
|
Tailscale, with nginx caching, gzip, HTTP/2, TLS session reuse, and upstream
|
||||||
|
keepalive
|
||||||
|
|
||||||
Run `./lab.sh up` and `./lab.sh nuke` only from the Debian homelab server. The
|
Run `./lab.sh up` and `./lab.sh nuke` only from the Debian homelab server. The
|
||||||
script intentionally refuses to run from non-Debian machines so a laptop cannot
|
script intentionally refuses to run from non-Debian machines so a laptop cannot
|
||||||
|
|
@ -61,6 +65,9 @@ accidentally modify the cluster.
|
||||||
- registers Argo CD Applications from the `applications` map
|
- registers Argo CD Applications from the `applications` map
|
||||||
- passes the website image produced by the build step into Argo CD as a
|
- passes the website image produced by the build step into Argo CD as a
|
||||||
Kustomize image override
|
Kustomize image override
|
||||||
|
- deploys the tuned website runtime: Apache listens on port 8080, PHP-FPM
|
||||||
|
listens on loopback inside the container, OPcache is enabled, and
|
||||||
|
pre-rendered HTML handles the read-heavy pages
|
||||||
- default apps are `container-registry`, `website-production`,
|
- default apps are `container-registry`, `website-production`,
|
||||||
`demos-static`, and `heimdall`
|
`demos-static`, and `heimdall`
|
||||||
|
|
||||||
|
|
@ -69,6 +76,8 @@ accidentally modify the cluster.
|
||||||
- uploads nginx, HAProxy, Varnish, and Squid configs
|
- uploads nginx, HAProxy, Varnish, and Squid configs
|
||||||
- obtains and renews Let's Encrypt certificates for the configured hostname
|
- obtains and renews Let's Encrypt certificates for the configured hostname
|
||||||
- runs the edge cache/proxy chain with Docker Compose
|
- runs the edge cache/proxy chain with Docker Compose
|
||||||
|
- enables gzip, HTTP/2, TLS session reuse, client keepalive, upstream
|
||||||
|
keepalive, and cache headers for the public website path
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
|
|
@ -134,6 +143,16 @@ Build metadata is written under `.lab/` so repeat runs can skip the website
|
||||||
or demos image build when the source hash, platform, image reference, and
|
or demos image build when the source hash, platform, image reference, and
|
||||||
registry manifest still match.
|
registry manifest still match.
|
||||||
|
|
||||||
|
The website build is intentionally performed on the Debian homelab path and the
|
||||||
|
Gitea Actions runner, not on a laptop. The current image uses
|
||||||
|
`php:8.5-fpm-alpine`, installs Apache, routes PHP through PHP-FPM, enables
|
||||||
|
OPcache for immutable image deploys, and runs
|
||||||
|
`apps/website/render-static-pages.sh` during the image build. That render step
|
||||||
|
produces static HTML for `/`, `/cv.php`, `/blog.php`, `/demos.php`, and
|
||||||
|
`/homelab-tree.php` in the static languages. Runtime PHP remains for write and
|
||||||
|
translation endpoints such as `save_idea.php`, `visitor_ideas.php`,
|
||||||
|
`translate.php`, and `save_lang.php`.
|
||||||
|
|
||||||
Set `LAB_GITEA_DEPLOY=false` to skip the external Gitea deployment step when the
|
Set `LAB_GITEA_DEPLOY=false` to skip the external Gitea deployment step when the
|
||||||
Raspberry Pi service is already managed manually. The default Gitea target is
|
Raspberry Pi service is already managed manually. The default Gitea target is
|
||||||
`jv@192.168.100.89`, install directory `/opt/homelab-gitea`, HTTP port `3000`,
|
`jv@192.168.100.89`, install directory `/opt/homelab-gitea`, HTTP port `3000`,
|
||||||
|
|
@ -372,6 +391,16 @@ proxies to Gitea on the Raspberry Pi at the configured `gitea_backend_port`
|
||||||
instead of Traefik. This keeps public read-only source browsing available even
|
instead of Traefik. This keeps public read-only source browsing available even
|
||||||
when the cluster has been destroyed.
|
when the cluster has been destroyed.
|
||||||
|
|
||||||
|
For the main website, nginx terminates TLS, serves cached HTML and static
|
||||||
|
assets, compresses text responses with gzip, advertises HTTP/2, reuses TLS
|
||||||
|
sessions, and keeps upstream connections open to the Traefik backend. The
|
||||||
|
application side marks pre-rendered HTML as
|
||||||
|
`Cache-Control: public, max-age=300, s-maxage=3600`; the edge keeps CSS and JS
|
||||||
|
under the stronger immutable asset policy. In local measurements, cached
|
||||||
|
single-resource requests are dominated by the remote TCP/TLS path, while a
|
||||||
|
reused HTTP/2 asset batch completes in roughly 60 ms after the connection is
|
||||||
|
established.
|
||||||
|
|
||||||
Use the configured `server_name` in the browser, for example
|
Use the configured `server_name` in the browser, for example
|
||||||
`https://lab2025.duckdns.org`. A raw OCI IP address will still show a browser
|
`https://lab2025.duckdns.org`. A raw OCI IP address will still show a browser
|
||||||
certificate warning because the trusted certificate is issued for the hostname.
|
certificate warning because the trusted certificate is issued for the hostname.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Website Runtime
|
||||||
|
|
||||||
|
The portfolio website keeps Apache at the core while moving PHP execution to
|
||||||
|
PHP-FPM.
|
||||||
|
|
||||||
|
## Runtime Shape
|
||||||
|
|
||||||
|
- Base image: `php:8.5-fpm-alpine`
|
||||||
|
- Web server: Alpine Apache, listening on container port `8080`
|
||||||
|
- PHP runtime: PHP-FPM on `127.0.0.1:9000`
|
||||||
|
- PHP cache: OPcache enabled, with timestamp validation disabled for immutable
|
||||||
|
image deploys
|
||||||
|
- Dynamic storage: `/var/www/localhost/htdocs/db` mounted from the retained
|
||||||
|
`website-db` PVC
|
||||||
|
|
||||||
|
Apache routes `*.php` through `proxy_fcgi` to PHP-FPM. The startup script starts
|
||||||
|
PHP-FPM in the background and then runs Apache in the foreground.
|
||||||
|
|
||||||
|
## Static Render Path
|
||||||
|
|
||||||
|
`render-static-pages.sh` runs during the image build and renders static HTML
|
||||||
|
for the read-heavy pages:
|
||||||
|
|
||||||
|
- `/`
|
||||||
|
- `/cv.php`
|
||||||
|
- `/blog.php`
|
||||||
|
- `/demos.php`
|
||||||
|
- `/homelab-tree.php`
|
||||||
|
|
||||||
|
Static output is generated for the committed static languages under
|
||||||
|
`/static-pages/<lang>/`. Apache rewrites supported static-language requests to
|
||||||
|
those generated HTML files. Requests for runtime-generated languages still fall
|
||||||
|
through to PHP so the translation workflow continues to work.
|
||||||
|
|
||||||
|
`blog.php` no longer renders visitor ideas directly into the HTML. Recent ideas
|
||||||
|
are served by `visitor_ideas.php` and loaded by `visitor-ideas.js`, which keeps
|
||||||
|
the blog page cacheable while preserving the write path through `save_idea.php`.
|
||||||
|
|
||||||
|
## Cache Path
|
||||||
|
|
||||||
|
The website sets cache headers for pre-rendered HTML:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cache-Control: public, max-age=300, s-maxage=3600
|
||||||
|
```
|
||||||
|
|
||||||
|
Dynamic write and translation endpoints are marked `no-store`:
|
||||||
|
|
||||||
|
- `save_idea.php`
|
||||||
|
- `visitor_ideas.php`
|
||||||
|
- `translate.php`
|
||||||
|
- `save_lang.php`
|
||||||
|
|
||||||
|
The OCI edge nginx layer handles gzip, cache HITs, HTTP/2, TLS session reuse,
|
||||||
|
client keepalive, and upstream keepalive to the Traefik backend. CSS and
|
||||||
|
JavaScript keep the edge's longer immutable asset policy.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Do not build images locally. The image is built and deployed by the Debian
|
||||||
|
homelab path and Gitea Actions.
|
||||||
|
|
||||||
|
Local source validation that does not build the image:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
shellcheck apps/website/start-website.sh apps/website/render-static-pages.sh
|
||||||
|
find apps/website -name "*.php" -print0 | xargs -0 -n1 php -l
|
||||||
|
node --check apps/website/visitor-ideas.js
|
||||||
|
kubectl kustomize apps/website >/tmp/website-kustomize.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
Static rendering can be checked without Docker by copying the app to a temporary
|
||||||
|
directory and running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sh render-static-pages.sh /path/to/copied/apps/website
|
||||||
|
```
|
||||||
|
|
@ -15,6 +15,8 @@ $activityKeys = [
|
||||||
'blog_activity_11',
|
'blog_activity_11',
|
||||||
'blog_activity_12',
|
'blog_activity_12',
|
||||||
'blog_activity_13',
|
'blog_activity_13',
|
||||||
|
'blog_activity_14',
|
||||||
|
'blog_activity_15',
|
||||||
];
|
];
|
||||||
|
|
||||||
$todoKeys = [
|
$todoKeys = [
|
||||||
|
|
@ -52,6 +54,7 @@ $stackKeys = [
|
||||||
'blog_stack_14',
|
'blog_stack_14',
|
||||||
'blog_stack_15',
|
'blog_stack_15',
|
||||||
'blog_stack_16',
|
'blog_stack_16',
|
||||||
|
'blog_stack_17',
|
||||||
];
|
];
|
||||||
|
|
||||||
$caseStudyCards = [
|
$caseStudyCards = [
|
||||||
|
|
@ -158,6 +161,12 @@ $stackSourceLinks = [
|
||||||
['label' => 'platform/main.tf', 'path' => 'bootstrap/platform/main.tf'],
|
['label' => 'platform/main.tf', 'path' => 'bootstrap/platform/main.tf'],
|
||||||
['label' => 'README monitoring', 'path' => 'README.md'],
|
['label' => 'README monitoring', 'path' => 'README.md'],
|
||||||
],
|
],
|
||||||
|
'blog_stack_17' => [
|
||||||
|
['label' => 'website Dockerfile', 'path' => 'apps/website/Dockerfile'],
|
||||||
|
['label' => 'static renderer', 'path' => 'apps/website/render-static-pages.sh'],
|
||||||
|
['label' => 'Apache/FPM config', 'path' => 'apps/website/httpd-php-fpm.conf'],
|
||||||
|
['label' => 'edge nginx template', 'path' => 'bootstrap/edge/templates/default.conf.tftpl'],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $sourceBase): void {
|
function renderStackSourceLinks(string $stackKey, array $sourceLinks, string $sourceBase): void {
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ 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 case-study style walkthrough of how a Debian control plane, Pimox app workers, external Gitea, local registry, Kyverno policy, Argo CD, monitoring, and static demo shelf became a repeatable Kubernetes delivery path.',
|
'blog_subtitle' => 'A case-study style walkthrough of how a Debian control plane, Pimox app workers, external Gitea, local registry, Kyverno policy, Argo CD, monitoring, static demos, and a tuned website path became a repeatable Kubernetes delivery system.',
|
||||||
'case_studies_kicker' => 'Portfolio case studies',
|
'case_studies_kicker' => 'Portfolio case studies',
|
||||||
'case_studies_title' => 'Production-shaped evidence',
|
'case_studies_title' => 'Production-shaped evidence',
|
||||||
'case_studies_intro' => 'These are the three proof points a hiring manager should see first: platform ownership, production reliability at scale, and the reserved MLOps path for model-serving work.',
|
'case_studies_intro' => 'These are the three proof points a hiring manager should see first: platform ownership, production reliability at scale, and the reserved MLOps path for model-serving work.',
|
||||||
|
|
@ -137,7 +137,7 @@ return [
|
||||||
'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_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 and now runs on app workers: 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 and now runs on app workers: 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, HTTP/2, keepalive, gzip, and caching stay outside the home network while Tailscale carries traffic back to Traefik.',
|
||||||
'blog_stack_7' => 'The shared theme toggle is plain CSS and JavaScript: dark mode uses an old-console green-on-black treatment, while light mode switches to black cursive on ivory across the website and demo catalog.',
|
'blog_stack_7' => 'The shared theme toggle is plain CSS and JavaScript: dark mode uses an old-console green-on-black treatment, while light mode switches to black cursive on ivory across the website and demo catalog.',
|
||||||
'blog_stack_8' => 'The first demo keeps files in the browser. Image crunching uses native Canvas APIs today, while the fast serious path for video conversion is Rust compiled to WebAssembly with a TypeScript UI.',
|
'blog_stack_8' => 'The first demo keeps files in the browser. Image crunching uses native Canvas APIs today, while the fast serious path for video conversion is Rust compiled to WebAssembly with a TypeScript UI.',
|
||||||
'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, model-drift simulation, and the reserved MLOps platform page.',
|
'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, model-drift simulation, and the reserved MLOps platform page.',
|
||||||
|
|
@ -148,6 +148,7 @@ return [
|
||||||
'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_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_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, Loki, Promtail, node-exporter, and kube-state-metrics, with placement guardrails so platform add-ons stop defaulting to the control plane.',
|
'blog_stack_16' => 'The monitoring layer now includes Prometheus Stack, Grafana, Loki, Promtail, node-exporter, and kube-state-metrics, with placement guardrails so platform add-ons stop defaulting to the control plane.',
|
||||||
|
'blog_stack_17' => 'The portfolio website keeps Apache at the core, runs PHP through PHP-FPM with OPcache, pre-renders read-heavy pages into static HTML during the image build, and leaves PHP for write and translation endpoints.',
|
||||||
'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 from the app workers. The infrastructure path stays manual through lab.sh, including the PXE/Pimox template builder, NVMe-backed worker clones, Kyverno policy placement, and the opt-in OpenWrt firewall VM, 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 from the app workers. The infrastructure path stays manual through lab.sh, including the PXE/Pimox template builder, NVMe-backed worker clones, Kyverno policy placement, and the opt-in OpenWrt firewall VM, while the OCI edge routes public traffic back through the private path.',
|
||||||
|
|
@ -155,7 +156,7 @@ return [
|
||||||
'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',
|
||||||
'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, controller placement, 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, controller placement, measured website performance, and deploys that match the exact commit that passed validation.',
|
||||||
'blog_activity_1' => 'Moved Gitea out of Kubernetes and onto the Raspberry Pi as the local Git service, while keeping the public /git/ route through the edge stack.',
|
'blog_activity_1' => 'Moved Gitea out of Kubernetes and onto the Raspberry Pi as the local Git service, while keeping 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_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.',
|
'blog_activity_3' => 'Added a custom checkout flow for the /git/ subpath and kept a persistent Debian checkout for the deployment scripts.',
|
||||||
|
|
@ -169,6 +170,8 @@ return [
|
||||||
'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_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_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 and moved platform add-ons such as Argo CD, Kyverno, and prometheus-stack work toward app-worker placement instead of treating the control plane as spare capacity.',
|
'blog_activity_13' => 'Installed the monitoring stack and moved platform add-ons such as Argo CD, Kyverno, and prometheus-stack work toward app-worker placement instead of treating the control plane as spare capacity.',
|
||||||
|
'blog_activity_14' => 'Reworked the website image to keep Apache as the web server while moving PHP execution to PHP-FPM, enabling OPcache, and validating the runtime through Gitea Actions instead of local image builds.',
|
||||||
|
'blog_activity_15' => 'Pre-rendered the read-heavy website pages into static HTML, moved visitor ideas behind a small JSON endpoint, added cache headers, enabled HTTP/2 and connection reuse at the OCI edge, and measured reused HTTP/2 asset loads around 60ms.',
|
||||||
'blog_todo_kicker' => 'Improvement backlog',
|
'blog_todo_kicker' => 'Improvement backlog',
|
||||||
'blog_todo_title' => 'Todo list for the next homelab pass',
|
'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.',
|
'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.',
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ 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' => 'Case-study style tlahcuilolli: quen Debian control plane, Pimox app workers, external Gitea, local registry, Kyverno policy, Argo CD, monitoring, ihuan static demo shelf omocuepque repeatable Kubernetes delivery path.',
|
'blog_subtitle' => 'Case-study style tlahcuilolli: quen Debian control plane, Pimox app workers, external Gitea, local registry, Kyverno policy, Argo CD, monitoring, static demos, ihuan tuned website path omocuepque repeatable Kubernetes delivery system.',
|
||||||
'case_studies_kicker' => 'Portfolio tlamantli',
|
'case_studies_kicker' => 'Portfolio tlamantli',
|
||||||
'case_studies_title' => 'Evidence quen production',
|
'case_studies_title' => 'Evidence quen production',
|
||||||
'case_studies_intro' => 'Inin yeyi proof points ma quitta hiring manager achto: platform ownership, production reliability at scale, ihuan reserved MLOps path para model-serving tequitl.',
|
'case_studies_intro' => 'Inin yeyi proof points ma quitta hiring manager achto: platform ownership, production reliability at scale, ihuan reserved MLOps path para model-serving tequitl.',
|
||||||
|
|
@ -137,7 +137,7 @@ return [
|
||||||
'blog_stack_3' => 'OpenTofu quichihua cluster, platform, apps, edge, ihuan provisioning layers repeatable, pampa "I swear I remember the command" amo disaster recovery strategy.',
|
'blog_stack_3' => 'OpenTofu quichihua cluster, platform, apps, edge, ihuan provisioning layers repeatable, pampa "I swear I remember the command" amo disaster recovery strategy.',
|
||||||
'blog_stack_4' => 'Calico handles pod networking, ihuan OpenEBS hostpath storage keeps important data after rebuilds, pampa deleting everything by accident zan funny once.',
|
'blog_stack_4' => 'Calico handles pod networking, ihuan OpenEBS hostpath storage keeps important data after rebuilds, pampa deleting everything by accident zan funny once.',
|
||||||
'blog_stack_5' => 'Argo CD quimaca GitOps referee ihuan now runs on app workers: manifests cateh ipan Git, cluster follows along, ihuan manual drift gets side-eyed back into place.',
|
'blog_stack_5' => 'Argo CD quimaca GitOps referee ihuan now runs on app workers: manifests cateh ipan Git, cluster follows along, ihuan manual drift gets side-eyed back into place.',
|
||||||
'blog_stack_6' => 'OCI edge host runs nginx, HAProxy, Varnish, ihuan Squid para TLS, routing, ihuan caching stay outside home network while Tailscale quihuica traffic back to worker node.',
|
'blog_stack_6' => 'OCI edge host runs nginx, HAProxy, Varnish, ihuan Squid para TLS, routing, HTTP/2, keepalive, gzip, ihuan caching ma mocahua outside home network mientras Tailscale quihuica traffic back to Traefik.',
|
||||||
'blog_stack_7' => 'Shared theme toggle quipia plain CSS ihuan JavaScript: dark mode old-console green-on-black, light mode black cursive on ivory ipan website ihuan demo catalog.',
|
'blog_stack_7' => 'Shared theme toggle quipia plain CSS ihuan JavaScript: dark mode old-console green-on-black, light mode black cursive on ivory ipan website ihuan demo catalog.',
|
||||||
'blog_stack_8' => 'First demo keeps files ipan browser. Image crunching uses native Canvas APIs axcan, while fast serious path para video conversion is Rust compiled to WebAssembly ika TypeScript UI.',
|
'blog_stack_8' => 'First demo keeps files ipan browser. Image crunching uses native Canvas APIs axcan, while fast serious path para video conversion is Rust compiled to WebAssembly ika TypeScript UI.',
|
||||||
'blog_stack_9' => 'Yancuic demos cover network jitter graphs, local JSON/JWT/log tools, architecture simulator, offline traveler converter, redactor prototype, sentiment analysis, model-drift simulation, ihuan reserved MLOps platform page.',
|
'blog_stack_9' => 'Yancuic demos cover network jitter graphs, local JSON/JWT/log tools, architecture simulator, offline traveler converter, redactor prototype, sentiment analysis, model-drift simulation, ihuan reserved MLOps platform page.',
|
||||||
|
|
@ -148,6 +148,7 @@ return [
|
||||||
'blog_stack_14' => 'Worker clone automation is count-based ihuan idempotent: LAB_PIMOX_WORKER_COUNT=1 quitosnequi ensure VM 9010 exists, amo create fresh worker every run. New workers refused tla target storage is local.',
|
'blog_stack_14' => 'Worker clone automation is count-based ihuan idempotent: LAB_PIMOX_WORKER_COUNT=1 quitosnequi ensure VM 9010 exists, amo create fresh worker every run. New workers refused tla target storage is local.',
|
||||||
'blog_stack_15' => 'OpenWrt handled separately from Debian golden-node template. Lab downloads upstream ARM SystemReady EFI image, imports it as VM 9050 on nvme_thin_pool, ihuan keeps disabled unless LAB_OPENWRT_VM=true.',
|
'blog_stack_15' => 'OpenWrt handled separately from Debian golden-node template. Lab downloads upstream ARM SystemReady EFI image, imports it as VM 9050 on nvme_thin_pool, ihuan keeps disabled unless LAB_OPENWRT_VM=true.',
|
||||||
'blog_stack_16' => 'Monitoring layer axcan includes Prometheus Stack, Grafana, Loki, Promtail, node-exporter, ihuan kube-state-metrics, ika placement guardrails para platform add-ons ma amo default to control plane.',
|
'blog_stack_16' => 'Monitoring layer axcan includes Prometheus Stack, Grafana, Loki, Promtail, node-exporter, ihuan kube-state-metrics, ika placement guardrails para platform add-ons ma amo default to control plane.',
|
||||||
|
'blog_stack_17' => 'Portfolio website keeps Apache at core, runs PHP through PHP-FPM ika OPcache, pre-renders read-heavy pages into static HTML during image build, ihuan leaves PHP para write ihuan translation endpoints.',
|
||||||
'blog_arch_kicker' => 'Architecture mapa',
|
'blog_arch_kicker' => 'Architecture mapa',
|
||||||
'blog_arch_title' => 'Homelab, end to end',
|
'blog_arch_title' => 'Homelab, end to end',
|
||||||
'blog_arch_intro' => 'Current delivery path starts ika push to Gitea, runs local validation, builds arm64 images, syncs validated commit into GitOps mirror, ihuan lets Argo CD reconcile from app workers. Infrastructure path stays manual through lab.sh, including PXE/Pimox template builder, NVMe-backed worker clones, Kyverno policy placement, ihuan opt-in OpenWrt firewall VM, while OCI edge routes public traffic back through private path.',
|
'blog_arch_intro' => 'Current delivery path starts ika push to Gitea, runs local validation, builds arm64 images, syncs validated commit into GitOps mirror, ihuan lets Argo CD reconcile from app workers. Infrastructure path stays manual through lab.sh, including PXE/Pimox template builder, NVMe-backed worker clones, Kyverno policy placement, ihuan opt-in OpenWrt firewall VM, while OCI edge routes public traffic back through private path.',
|
||||||
|
|
@ -155,7 +156,7 @@ return [
|
||||||
'blog_arch_fun_link' => 'Xiquitta Christmas-tree version',
|
'blog_arch_fun_link' => 'Xiquitta Christmas-tree version',
|
||||||
'blog_activity_kicker' => 'Yancuic activity log',
|
'blog_activity_kicker' => 'Yancuic activity log',
|
||||||
'blog_activity_title' => 'Tlein omopatla since first build',
|
'blog_activity_title' => 'Tlein omopatla since first build',
|
||||||
'blog_activity_intro' => 'Lab omocuep de working Kubernetes experiment into more complete self-hosted delivery system. Latest work focused on trust, repeatability, VM-based expansion, controller placement, ihuan making deploys match exact commit in passed validation.',
|
'blog_activity_intro' => 'Lab omocuep de working Kubernetes experiment into more complete self-hosted delivery system. Latest work focused on trust, repeatability, VM-based expansion, controller placement, measured website performance, ihuan deploys in match exact commit in passed validation.',
|
||||||
'blog_activity_1' => 'Moved Gitea out of Kubernetes ihuan onto Raspberry Pi as local Git service, while keeping public /git/ route through edge stack.',
|
'blog_activity_1' => 'Moved Gitea out of Kubernetes ihuan onto Raspberry Pi as local Git service, while keeping public /git/ route through edge stack.',
|
||||||
'blog_activity_2' => 'Installed ihuan validated Debian-hosted Gitea Actions runner para pushes to main can build, scan, ihuan deploy without laptop session.',
|
'blog_activity_2' => 'Installed ihuan validated Debian-hosted Gitea Actions runner para pushes to main can build, scan, ihuan deploy without laptop session.',
|
||||||
'blog_activity_3' => 'Added custom checkout flow para /git/ subpath ihuan kept persistent Debian checkout para deployment scripts.',
|
'blog_activity_3' => 'Added custom checkout flow para /git/ subpath ihuan kept persistent Debian checkout para deployment scripts.',
|
||||||
|
|
@ -169,6 +170,8 @@ return [
|
||||||
'blog_activity_11' => 'Added NVMe-backed Pimox worker clone automation para VM 9000 ma mocahua ipan local storage mientras worker nodes mochihuah ipan nvme_thin_pool.',
|
'blog_activity_11' => 'Added NVMe-backed Pimox worker clone automation para VM 9000 ma mocahua ipan local storage mientras worker nodes mochihuah ipan nvme_thin_pool.',
|
||||||
'blog_activity_12' => 'Added opt-in OpenWrt VM path para simple firewall between vmbr0 ihuan vmbr1, ika guardrails in avoid Orange Pi host networking changes.',
|
'blog_activity_12' => 'Added opt-in OpenWrt VM path para simple firewall between vmbr0 ihuan vmbr1, ika guardrails in avoid Orange Pi host networking changes.',
|
||||||
'blog_activity_13' => 'Installed monitoring stack ihuan moved platform add-ons such as Argo CD, Kyverno, ihuan prometheus-stack toward app-worker placement instead of treating control plane as spare capacity.',
|
'blog_activity_13' => 'Installed monitoring stack ihuan moved platform add-ons such as Argo CD, Kyverno, ihuan prometheus-stack toward app-worker placement instead of treating control plane as spare capacity.',
|
||||||
|
'blog_activity_14' => 'Reworked website image para Apache ma mocahua web server while PHP runs through PHP-FPM, OPcache enabled, ihuan runtime validated through Gitea Actions instead of local image builds.',
|
||||||
|
'blog_activity_15' => 'Pre-rendered read-heavy website pages into static HTML, moved visitor ideas behind small JSON endpoint, added cache headers, enabled HTTP/2 ihuan connection reuse at OCI edge, ihuan measured reused HTTP/2 asset loads around 60ms.',
|
||||||
'blog_todo_kicker' => 'Improvement tlatecpanaliztli',
|
'blog_todo_kicker' => 'Improvement tlatecpanaliztli',
|
||||||
'blog_todo_title' => 'Todo list para next homelab pass',
|
'blog_todo_title' => 'Todo list para next homelab pass',
|
||||||
'blog_todo_intro' => 'Inin cateh improvement proposals, amo chores zan pampa chores. Each item either reduces rebuild risk, tightens supply-chain hygiene, o makes platform easier to operate quema tlein fails.',
|
'blog_todo_intro' => 'Inin cateh improvement proposals, amo chores zan pampa chores. Each item either reduces rebuild risk, tightens supply-chain hygiene, o makes platform easier to operate quema tlein fails.',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue