<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Home on Landry Zetam - Tech Blog</title><link>https://blog.landryzetam.net/</link><description>Recent content in Home on Landry Zetam - Tech Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 10 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.landryzetam.net/index.xml" rel="self" type="application/rss+xml"/><item><title>The Full Architecture of My Kubernetes Agents</title><link>https://blog.landryzetam.net/posts/kubernetes-agents-full-architecture/</link><pubDate>Mon, 10 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/kubernetes-agents-full-architecture/</guid><description>&lt;p>Five agents run against my K3s cluster. Three of them form a closed loop — one detects problems, one fixes them, one reviews the fix — and none of the three can do another&amp;rsquo;s job. This is everything about how they&amp;rsquo;re built: the framework, the prompt assembly, every tool, both safety gates, the memory layers, and a real pull request one of them opened.&lt;/p>
&lt;p>Then I merged it and spent a day fixing what production found. Eight more bugs, none of them in the agent logic — §17 onward is that day, and it&amp;rsquo;s the more useful half.&lt;/p></description></item><item><title>NetworkPolicy vs AuthorizationPolicy: One Decides If the Call Connects, the Other Decides If Anyone Answers</title><link>https://blog.landryzetam.net/posts/network-policy-vs-authorization-policy/</link><pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/network-policy-vs-authorization-policy/</guid><description>&lt;p>Kubernetes gives you two resources that both look like &amp;ldquo;firewall rules for pods,&amp;rdquo; and most teams deploy one and assume they got the other for free. They didn&amp;rsquo;t. The two policies operate at different layers, speak different languages, and fail in completely different ways — and you almost certainly need both.&lt;/p>
&lt;h2 id="the-setup">The Setup&lt;/h2>
&lt;p>Picture a cluster running a service mesh (Istio, in my case) with a typical three-tier layout: an ingress gateway, a handful of API services, and a PostgreSQL database listening on port 5432. The security requirement sounds simple: only the API services should reach the database, and only the gateway should reach the APIs. The first instinct is to reach for &lt;em>a&lt;/em> policy — and Kubernetes hands you two that both claim to do this. &lt;code>NetworkPolicy&lt;/code> ships with Kubernetes itself (enforced by your CNI — Cilium, Calico). &lt;code>AuthorizationPolicy&lt;/code> ships with Istio (enforced by the Envoy sidecar). Same goal on paper, very different machinery underneath.&lt;/p></description></item><item><title>Lint Your Network Before It Exists: IaC Policy Scanning for VPCs</title><link>https://blog.landryzetam.net/posts/lint-your-network-before-it-exists/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/lint-your-network-before-it-exists/</guid><description>&lt;p>Most network security failures aren&amp;rsquo;t exotic. They&amp;rsquo;re a security group left open to the whole internet on port 22, a subnet that auto-assigns public IPs to everything you launch into it, or a virtual network with flow logs never turned on so you have no record of what happened. The surprise isn&amp;rsquo;t that these slip through — it&amp;rsquo;s that you can catch every one of them &lt;em>before a single resource exists&lt;/em>, by linting the infrastructure code the same way you lint application code.&lt;/p></description></item><item><title>Exploring Torsional Vibration Through MATLAB Simulation: An Academic Approach</title><link>https://blog.landryzetam.net/posts/torsional-vibration-matlab-simulation/</link><pubDate>Wed, 24 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/torsional-vibration-matlab-simulation/</guid><description>&lt;p>Torsional vibration in drill strings is a recognized problem in oil and gas drilling that is difficult to measure directly downhole and challenging to predict with simple rules. A Master&amp;rsquo;s thesis explored how mathematical simulation might help understand these oscillations—not by solving the problem definitively, but by building a theoretical model to investigate the mechanisms.&lt;/p>
&lt;p>This post examines that exploratory work: how a two-degree-of-freedom mathematical model, implemented in MATLAB, can be used to investigate stick-slip behavior and explore potential mitigation approaches. The emphasis is on &lt;em>methodology&lt;/em> and &lt;em>investigation&lt;/em>, not on solutions proven to work in practice.&lt;/p></description></item><item><title>Building a Production-Grade Home Network with UniFi VLANs</title><link>https://blog.landryzetam.net/posts/unifi-vlan-home-network/</link><pubDate>Tue, 23 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/unifi-vlan-home-network/</guid><description>&lt;p>Your home network doesn&amp;rsquo;t have to be a flat, insecure mess where your smart toaster can talk to your NAS. With UniFi gear and some intentional design, you can build network segmentation that rivals enterprise setups—without the enterprise price tag. This is how I architected a 10-VLAN home network that isolates everything from security cameras to a 7-node Kubernetes cluster.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-the-design-philosophy">Part 1: The Design Philosophy&lt;/h2>
&lt;h3 id="why-segment-at-all">Why Segment at All?&lt;/h3>
&lt;p>Most home networks run everything on a single subnet. Your laptop, your Ring cameras, your kids&amp;rsquo; tablets, and your IoT light bulbs all share the same network space. This creates several problems:&lt;/p></description></item><item><title>GitOps Framework: How the Fako Cluster Repository is Organized</title><link>https://blog.landryzetam.net/posts/gitops-framework/</link><pubDate>Sun, 21 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/gitops-framework/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>The Fako Cluster uses a GitOps approach where &lt;strong>Git is the single source of truth&lt;/strong> for all cluster state. Every deployment, configuration change, and infrastructure update flows through Git commits. FluxCD watches the repository and automatically reconciles the cluster to match the desired state defined in code.&lt;/p>
&lt;p>This post explains the repository structure, the reasoning behind each directory, and how the pieces work together.&lt;/p>
&lt;h2 id="repository-structure">Repository Structure&lt;/h2>
&lt;pre tabindex="0">&lt;code>fako-cluster/
├── apps/ # Application deployments
│ ├── base/ # Base Kustomize configurations
│ └── staging/ # Environment overlay (what actually deploys)
├── clusters/ # Cluster bootstrap and Flux config
│ └── staging/ # Flux Kustomizations that orchestrate everything
├── infrastructure/ # Platform components
│ ├── controllers/ # Operators (Cert-Manager, CloudNative-PG, etc.)
│ └── configs/ # Configuration for controllers
├── monitoring/ # Observability stack
│ ├── controllers/ # Prometheus, Loki, Grafana, etc.
│ └── configs/ # Dashboards, alerting rules
├── scripts/ # Deployment and maintenance scripts
└── notes/ # Documentation and troubleshooting
&lt;/code>&lt;/pre>&lt;h2 id="the-basestaging-pattern">The Base/Staging Pattern&lt;/h2>
&lt;p>The most important concept to understand is the &lt;strong>base/staging pattern&lt;/strong> used throughout the repository.&lt;/p></description></item><item><title>From Transcripts to Summaries: Completing the Audio Pipeline</title><link>https://blog.landryzetam.net/posts/transcripts-to-summaries-audio-pipeline/</link><pubDate>Sat, 20 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/transcripts-to-summaries-audio-pipeline/</guid><description>&lt;p>Remember that audio transcription pipeline I built? Raw recordings flow in, get compressed, transcribed by Whisper, and stored as JSON. Great for archival, but 204 transcript files sitting on NFS storage aren&amp;rsquo;t exactly useful. Today I&amp;rsquo;ll show you how I completed the loop—automatically summarizing transcripts with an LLM and publishing everything to my Obsidian vault.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-the-problem-with-raw-transcripts">Part 1: The Problem with Raw Transcripts&lt;/h2>
&lt;p>The original pipeline worked beautifully. Every morning, new transcripts appeared as JSON files:&lt;/p></description></item><item><title>Complete Kubernetes Security Pipeline - Kube-bench and Kubescape to Obsidian</title><link>https://blog.landryzetam.net/posts/kubernetes-security-pipeline-kubebench-kubescape/</link><pubDate>Fri, 19 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/kubernetes-security-pipeline-kubebench-kubescape/</guid><description>&lt;p>What if your Kubernetes cluster could write comprehensive security reports directly into your second brain every night? Not just one perspective, but two complementary views: infrastructure security &lt;em>and&lt;/em> workload security. I built exactly that—a pipeline combining kube-bench (CIS benchmarks) and kubescape (NSA/MITRE frameworks) that publishes human-readable reports to Obsidian automatically. Here&amp;rsquo;s how the complete system works.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-why-you-need-both-tools">Part 1: Why You Need Both Tools&lt;/h2>
&lt;h3 id="the-security-visibility-gap">The Security Visibility Gap&lt;/h3>
&lt;p>Running a Kubernetes homelab means wearing many hats. Security scanning tools exist, but most people either:&lt;/p></description></item><item><title>Prometheus WAL Replay: When Your Metrics Database Can't Start Fast Enough</title><link>https://blog.landryzetam.net/posts/prometheus-wal-replay/</link><pubDate>Thu, 18 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/prometheus-wal-replay/</guid><description>&lt;p>There&amp;rsquo;s a special kind of frustration that comes from watching a pod restart 90 times over 37 hours, each time getting &lt;em>just&lt;/em> a little further before Kubernetes kills it again. Today I debugged a Prometheus instance stuck in an infinite crash loop, and the root cause was surprisingly subtle: the database was simply too large to start within the default health check window.&lt;/p>
&lt;p>This is the story of startup probes, Write-Ahead Logs, and why your monitoring system might be the hardest thing to monitor.&lt;/p></description></item><item><title>Building a Kubernetes Security Reporter for Obsidian</title><link>https://blog.landryzetam.net/posts/kubernetes-security-reporter-obsidian/</link><pubDate>Wed, 17 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/kubernetes-security-reporter-obsidian/</guid><description>&lt;p>What if your Kubernetes cluster could automatically write security reports directly into your second brain? Today I built exactly that—a system that runs CIS benchmark scans against my K3s cluster and publishes the results as beautifully formatted Obsidian notes. No more checking dashboards or parsing JSON files; just open your vault and see your cluster&amp;rsquo;s security posture.&lt;/p>
&lt;hr>
&lt;h2 id="part-1-the-problem">Part 1: The Problem&lt;/h2>
&lt;h3 id="security-visibility-in-a-homelab">Security Visibility in a Homelab&lt;/h3>
&lt;p>Running a Kubernetes homelab means wearing many hats: developer, operator, and security engineer. Tools like &lt;a href="https://github.com/aquasecurity/kube-bench">kube-bench&lt;/a> exist to scan your cluster against CIS benchmarks, but they typically output JSON or text that sits in a PersistentVolume gathering dust.&lt;/p></description></item><item><title>Creating Custom Docker MCP Servers: A Complete Guide</title><link>https://blog.landryzetam.net/posts/custom-docker-mcp-servers/</link><pubDate>Tue, 16 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/custom-docker-mcp-servers/</guid><description>&lt;p>If you&amp;rsquo;ve been using Docker&amp;rsquo;s MCP Toolkit to supercharge your AI workflows, you&amp;rsquo;ve probably wondered: &amp;ldquo;Can I build my own MCP server and integrate it with this system?&amp;rdquo; The answer is yes—but the documentation is scattered and the process has some gotchas that can trip you up. This guide walks you through everything you need to know to create, deploy, and troubleshoot custom MCP servers that work seamlessly with the Docker MCP Gateway.&lt;/p></description></item><item><title>Enabling DNS-01 TLS for Internal Kubernetes Services</title><link>https://blog.landryzetam.net/posts/dns01-tls-kubernetes-internal-services/</link><pubDate>Tue, 16 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/dns01-tls-kubernetes-internal-services/</guid><description>&lt;p>Ever visited a website and seen that little padlock icon in your browser? That&amp;rsquo;s TLS at work, encrypting the connection between you and the server. But what happens when you want that same security for services running on your home network that aren&amp;rsquo;t accessible from the internet? Today I solved this exact problem, and I want to walk you through not just &lt;em>how&lt;/em> I did it, but &lt;em>why&lt;/em> each piece matters.&lt;/p></description></item><item><title>Building an Automated Audio Transcription Pipeline on Kubernetes</title><link>https://blog.landryzetam.net/posts/audio-transcription-pipeline/</link><pubDate>Fri, 12 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/audio-transcription-pipeline/</guid><description>&lt;p>Every day, raw audio recordings land on an SFTP server. By morning, they&amp;rsquo;re compressed, transcribed, and stored as searchable JSON - all without human intervention. Here&amp;rsquo;s how I built this pipeline on my homelab Kubernetes cluster.&lt;/p>
&lt;h2 id="the-problem">The Problem&lt;/h2>
&lt;p>I had a growing collection of audio recordings that needed transcription. Manual processing wasn&amp;rsquo;t sustainable: download files, compress them, run through a transcription service, organize the output. This needed automation.&lt;/p>
&lt;p>The requirements were straightforward:&lt;/p></description></item><item><title>ChatBuddy - Voice AI Companion for Children</title><link>https://blog.landryzetam.net/posts/chatbuddy/</link><pubDate>Sun, 07 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/chatbuddy/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>ChatBuddy is an AI-powered voice companion designed specifically for children aged 3-8. When a child asks &amp;ldquo;Why is the sky blue?&amp;rdquo;, they get a fun, age-appropriate answer—not a Wikipedia article.&lt;/p>
&lt;p>The system runs entirely on-device with 5 containerized services on hardware with just 8GB RAM, ensuring complete privacy while delivering natural voice interactions with educational content grounded in verified facts.&lt;/p>
&lt;h3 id="why-build-this">Why Build This?&lt;/h3>
&lt;p>Kids don&amp;rsquo;t want to type. They want to talk. And they need answers that:&lt;/p></description></item><item><title>How I Clustered Three Mac Studios for Local AI Processing with GPUStack</title><link>https://blog.landryzetam.net/posts/gpustack-mac-clustering/</link><pubDate>Mon, 11 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/gpustack-mac-clustering/</guid><description>&lt;h2 id="opening-hook">Opening Hook&lt;/h2>
&lt;p>I&amp;rsquo;ve always loved the idea of running powerful AI workloads without relying on expensive cloud GPUs. Recently, I turned that idea into reality by transforming three Mac Studios into a fully functioning local AI cluster using &lt;strong>GPUStack&lt;/strong>. This setup lets me run distributed inference workloads across multiple Macs with Apple Metal acceleration — and it&amp;rsquo;s a lot more affordable and energy-efficient than most people think.&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Related:&lt;/strong> See &lt;a href="https://blog.landryzetam.net/posts/mac-ai-cluster/">Mac AI Cluster: From EXO Vision to GPUStack Reality&lt;/a> for the philosophical journey that led to this technical implementation.&lt;/p></description></item><item><title>NVIDIA vs Apple Silicon: The Architecture Battle That Shapes AI Models</title><link>https://blog.landryzetam.net/posts/nvidia-vs-apple-silicon-architecture/</link><pubDate>Mon, 11 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/nvidia-vs-apple-silicon-architecture/</guid><description>&lt;p>When I tell people I run AI models on Mac Studios instead of NVIDIA GPUs, I often get puzzled looks. &amp;ldquo;But NVIDIA is the gold standard!&amp;rdquo; they say. And they&amp;rsquo;re not wrong — but they&amp;rsquo;re also not seeing the full picture. The architectural differences between NVIDIA and Apple Silicon aren&amp;rsquo;t just technical minutiae; they fundamentally change how AI models work, how they&amp;rsquo;re trained, and what hardware they run best on.&lt;/p></description></item><item><title>Building a Local AI Cluster with Mac Hardware: From Vision to Reality</title><link>https://blog.landryzetam.net/posts/mac-ai-cluster/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/mac-ai-cluster/</guid><description>&lt;h2 id="the-mission-that-started-it-all">The Mission That Started It All&lt;/h2>
&lt;blockquote>
&lt;p>&lt;strong>Note:&lt;/strong> This post combines the journeys documented in my &lt;a href="https://blog.landryzetam.net/posts/mac-ai-cluster/">Mac AI Cluster Project&lt;/a> and &lt;a href="https://blog.landryzetam.net/posts/gpustack-mac-clustering/">GPUStack Mac Clustering Tutorial&lt;/a>. For deep technical details, see those project pages.&lt;/p>&lt;/blockquote>
&lt;p>When I first discovered &lt;strong>EXO Labs&lt;/strong>, their mission resonated deeply with me.&lt;/p>
&lt;blockquote>
&lt;p>Humanity is headed toward a world controlled by a handful of companies that will dictate the AI models everyone uses.
The real threat isn&amp;rsquo;t AI destroying us — it&amp;rsquo;s losing sovereignty over our own minds.&lt;/p></description></item><item><title>Building an Oura Ring Health Dashboard with Streamlit</title><link>https://blog.landryzetam.net/posts/oura-dashboard/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/oura-dashboard/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Oura Dashboard is a Streamlit-based web application deployed in the Fako cluster that provides interactive visualization of health data collected from the Oura Ring. It connects to the PostgreSQL database populated by the Oura Collector service and presents comprehensive health insights through charts, graphs, and analytics. The dashboard is secured with OAuth2 authentication and provides personalized health tracking capabilities for sleep, activity, readiness, and heart rate metrics.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Interactive Visualizations&lt;/strong>: Real-time charts and graphs using Streamlit&lt;/li>
&lt;li>&lt;strong>Comprehensive Metrics&lt;/strong>: Sleep, activity, readiness, and HRV analytics&lt;/li>
&lt;li>&lt;strong>OAuth2 Authentication&lt;/strong>: Secure access with OAuth2 proxy&lt;/li>
&lt;li>&lt;strong>PostgreSQL Integration&lt;/strong>: Direct database queries for data&lt;/li>
&lt;li>&lt;strong>Responsive Design&lt;/strong>: Mobile-friendly interface&lt;/li>
&lt;li>&lt;strong>Health Trends&lt;/strong>: Long-term pattern analysis&lt;/li>
&lt;li>&lt;strong>Custom Reports&lt;/strong>: Exportable health summaries&lt;/li>
&lt;li>&lt;strong>Real-time Updates&lt;/strong>: Auto-refresh capabilities&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Streamlit App&lt;/strong>: Python-based web dashboard&lt;/li>
&lt;li>&lt;strong>OAuth2 Proxy&lt;/strong>: Authentication layer&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP on port 8501&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access with authentication&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: AWS Secrets Manager integration&lt;/li>
&lt;li>&lt;strong>Database Connection&lt;/strong>: PostgreSQL read access&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 256Mi (request), 512Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 100m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: EmptyDir for temporary data&lt;/li>
&lt;li>&lt;strong>Port&lt;/strong>: 8501 (Streamlit default)&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>DATABASE_NAME&lt;/code>&lt;/td>
&lt;td>&lt;code>app&lt;/code>&lt;/td>
&lt;td>PostgreSQL database&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DAYS_TO_BACKFILL&lt;/code>&lt;/td>
&lt;td>&lt;code>7&lt;/code>&lt;/td>
&lt;td>Default data range&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>LOG_LEVEL&lt;/code>&lt;/td>
&lt;td>&lt;code>INFO&lt;/code>&lt;/td>
&lt;td>Application logging&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>API_TIMEOUT&lt;/code>&lt;/td>
&lt;td>&lt;code>30&lt;/code>&lt;/td>
&lt;td>Query timeout&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="oauth2-configuration">OAuth2 Configuration&lt;/h3>
&lt;p>Protected by OAuth2 proxy for secure access:&lt;/p></description></item><item><title>Home Assistant Voice Pipeline with Ollama</title><link>https://blog.landryzetam.net/posts/voice-pipeline/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/voice-pipeline/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>This implementation demonstrates a complete voice assistant pipeline using Wyoming Satellite with Home Assistant and Ollama as the AI brain, achieving natural conversation and smart home control entirely on-premises. The system transforms spoken words into meaningful actions through a sophisticated pipeline of AI models, all running locally for complete privacy.&lt;/p>
&lt;h2 id="why-ollama-for-voice">Why Ollama for Voice?&lt;/h2>
&lt;p>Voice assistants have unique requirements that Ollama handles beautifully:&lt;/p>
&lt;h3 id="speed-requirements">Speed Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Response Time&lt;/strong>: &amp;lt; 2 seconds for natural conversation&lt;/li>
&lt;li>&lt;strong>Model Loading&lt;/strong>: Pre-loaded models for instant responses&lt;/li>
&lt;li>&lt;strong>Streaming&lt;/strong>: Real-time token generation for faster perceived response&lt;/li>
&lt;/ul>
&lt;h3 id="privacy-first">Privacy First&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Local Processing&lt;/strong>: No cloud dependencies&lt;/li>
&lt;li>&lt;strong>Conversation History&lt;/strong>: Stored locally, never uploaded&lt;/li>
&lt;li>&lt;strong>Custom Wake Words&lt;/strong>: Combined with OpenWakeWord for complete privacy&lt;/li>
&lt;/ul>
&lt;h2 id="components-used">Components Used&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>OpenWakeWord&lt;/strong>: Wake word detection (&amp;ldquo;Hey Jarvis&amp;rdquo;)&lt;/li>
&lt;li>&lt;strong>Whisper&lt;/strong>: Speech-to-text transcription&lt;/li>
&lt;li>&lt;strong>Ollama (Qwen2.5:3b &amp;amp; Llama 8B)&lt;/strong>: Natural language understanding and response generation&lt;/li>
&lt;li>&lt;strong>Piper TTS&lt;/strong>: Text-to-speech synthesis&lt;/li>
&lt;li>&lt;strong>Home Assistant&lt;/strong>: Smart home orchestration and pipeline management&lt;/li>
&lt;li>&lt;strong>Wyoming Satellite&lt;/strong>: Voice satellite software on Raspberry Pi&lt;/li>
&lt;/ul>
&lt;h2 id="hardware-setup">Hardware Setup&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Raspberry Pi 5&lt;/strong> (2.4GHz, 4GB RAM) - Voice satellite device&lt;/li>
&lt;li>&lt;strong>ME6S USB Microphone&lt;/strong> - Audio input device&lt;/li>
&lt;li>&lt;strong>Bluetooth Speaker&lt;/strong> (88:92:CC:5D:CB:79) - Audio output via BlueALSA&lt;/li>
&lt;li>&lt;strong>Mini PC&lt;/strong> - Home Assistant server&lt;/li>
&lt;li>&lt;strong>Kubernetes Cluster&lt;/strong> - Container orchestration for AI services&lt;/li>
&lt;li>&lt;strong>NVIDIA GPU Node (yeezyai)&lt;/strong> - GPU acceleration for Ollama&lt;/li>
&lt;/ul>
&lt;h2 id="the-voice-pipeline-architecture">The Voice Pipeline Architecture&lt;/h2>
&lt;p>The voice pipeline runs entirely on the K8s homelab, with Ollama at its heart:&lt;/p></description></item><item><title>Powering Open WebUI and Cline with GPUStack: My AI Infrastructure Journey</title><link>https://blog.landryzetam.net/posts/local-ai-open-webui-cline/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/local-ai-open-webui-cline/</guid><description>&lt;p>After building my Mac AI cluster, I needed a way to make it accessible to all my tools. The journey took me through several frameworks before landing on the perfect solution: GPUStack providing an OpenAI-compatible API that seamlessly integrates with everything.&lt;/p>
&lt;h2 id="the-evolution-finding-the-right-framework">The Evolution: Finding the Right Framework&lt;/h2>
&lt;h3 id="the-journey">The Journey&lt;/h3>
&lt;p>My path to the current setup wasn&amp;rsquo;t straightforward:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>MLX Distributed Computing&lt;/strong>: Started here for model training and local inference on Apple Silicon&lt;/li>
&lt;li>&lt;strong>Exo Labs&lt;/strong>: Experimented with this promising framework, but pivoted when the community began a redesign&lt;/li>
&lt;li>&lt;strong>GPUStack&lt;/strong>: The solution that finally clicked - providing OpenAI-compatible endpoints that work with everything&lt;/li>
&lt;/ol>
&lt;h2 id="the-current-architecture">The Current Architecture&lt;/h2>
&lt;p>Here&amp;rsquo;s how my AI infrastructure actually works:&lt;/p></description></item><item><title>Technology Stack</title><link>https://blog.landryzetam.net/pages/stack/</link><pubDate>Fri, 08 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/stack/</guid><description>&lt;p>This page covers the complete technology landscape and tools that power my infrastructure and projects. Everything runs on a production-grade Kubernetes cluster, providing a solid foundation for experimentation and real-world deployments.&lt;/p>
&lt;h2 id="-how-the-k3s-cluster-works">🗺️ How the K3s Cluster Works&lt;/h2>
&lt;p>The whole platform runs on &lt;strong>K3s&lt;/strong> — a lightweight Kubernetes distribution — driven entirely by &lt;strong>GitOps&lt;/strong>. Nothing is changed by hand: I describe the desired state in Git, and the cluster continuously reconciles itself to match. The diagram below traces that loop end to end.&lt;/p></description></item><item><title>From GitHub Notes to Production Blog</title><link>https://blog.landryzetam.net/posts/hugo-blogging/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/hugo-blogging/</guid><description>&lt;h2 id="why-this-guide-exists">Why This Guide Exists&lt;/h2>
&lt;p>I&amp;rsquo;ve been doing a lot of dev work, research and hadn&amp;rsquo;t really thought about sharing the knowledge without having to learn frontend development or maintain complex code. I knew I had a bunch of markdown GitHub notes and thought they could be used as a baseline to catch up on all my lack of documentation. Then I found Hugo.&lt;/p>
&lt;p>This guide covers the entire workflow of creating a Hugo blog, containerizing it, and deploying it to Kubernetes - all without writing a single line of frontend code (html, css, js).&lt;/p></description></item><item><title>Powering My Voice Assistant with Ollama: Local AI for Home Automation</title><link>https://blog.landryzetam.net/posts/local-ai-with-ollama/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/local-ai-with-ollama/</guid><description>&lt;p>Ollama has become the AI brain of my home automation infrastructure, powering my voice assistant pipeline and Home Assistant integrations. Running entirely on-premises on my NVIDIA GPU node, it enables natural language understanding and intelligent responses while maintaining complete privacy and control.&lt;/p>
&lt;h2 id="the-home-automation-ai-hub">The Home Automation AI Hub&lt;/h2>
&lt;p>My Ollama deployment serves as the AI intelligence layer for home automation:&lt;/p>
&lt;p>&lt;img src="https://blog.landryzetam.net/posts/local-ai-with-ollama/img/homeassistantvoice_hu_25571ad08280435f.webp" alt="Home Automation AI Hub" width="1200" height="994" loading="lazy" decoding="async" />
&lt;em>Ollama serves as the AI brain for voice pipeline and Home Assistant automations&lt;/em>&lt;/p></description></item><item><title>Running 184 Pods on a 6-Node K3s Homelab Cluster</title><link>https://blog.landryzetam.net/posts/k8s/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/k8s/</guid><description>&lt;h2 id="project-overview">Project Overview&lt;/h2>
&lt;p>The Fako Cluster is my production Kubernetes environment that serves as the foundation for all other projects. It&amp;rsquo;s a self-hosted, production-grade K8s cluster that demonstrates enterprise-level practices while running on homelab hardware.&lt;/p>
&lt;h3 id="why-fako">Why &amp;ldquo;Fako&amp;rdquo;?&lt;/h3>
&lt;p>The name &amp;ldquo;Fako&amp;rdquo; holds special significance - it&amp;rsquo;s named after Mount Fako (Mount Cameroon), the highest peak in West and Central Africa. Just as Mount Fako stands as a towering landmark visible from miles away, this Kubernetes cluster serves as the foundational infrastructure that all other services can rely on.&lt;/p></description></item><item><title>Securing GitOps: SOPS Secret Management in k8s with FluxCD</title><link>https://blog.landryzetam.net/posts/secrets-management-with-sops-flux-gitops/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/secrets-management-with-sops-flux-gitops/</guid><description>&lt;h2 id="the-problem-secrets-in-gitops">The Problem: Secrets in GitOps&lt;/h2>
&lt;p>When I started my Kubernetes homelab journey, I quickly hit a wall that every GitOps practitioner faces: &lt;strong>How do you store secrets in Git without compromising security?&lt;/strong>&lt;/p>
&lt;p>The GitOps philosophy is beautifully simple - everything should be in Git. Your entire cluster state, all your applications, configurations, and yes, even secrets. But committing passwords, API keys, and certificates to a public (or even private) repository feels fundamentally wrong. It is wrong.&lt;/p></description></item><item><title>Self-Hosting n8n on Kubernetes for AI Automation</title><link>https://blog.landryzetam.net/posts/n8n/</link><pubDate>Thu, 07 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/n8n/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>N8N is an open-source workflow automation tool deployed in the Fako cluster. It provides a visual interface for creating complex automation workflows, integrating with hundreds of services and APIs. N8N allows you to automate repetitive tasks, connect different services, and build sophisticated data pipelines without extensive coding.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Visual Workflow Builder&lt;/strong>: Drag-and-drop interface for creating automations&lt;/li>
&lt;li>&lt;strong>200+ Integrations&lt;/strong>: Pre-built nodes for popular services&lt;/li>
&lt;li>&lt;strong>Self-Hosted&lt;/strong>: Full control over your data and workflows&lt;/li>
&lt;li>&lt;strong>PostgreSQL Backend&lt;/strong>: Reliable storage using the cluster&amp;rsquo;s PostgreSQL&lt;/li>
&lt;li>&lt;strong>Webhook Support&lt;/strong>: Trigger workflows via HTTP webhooks&lt;/li>
&lt;li>&lt;strong>Custom Functions&lt;/strong>: JavaScript code support for complex logic&lt;/li>
&lt;li>&lt;strong>Fair-Code License&lt;/strong>: Source available with sustainable business model&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment (stateful workflows)&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 5678&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access at &lt;code>n8n.landryzetam.net&lt;/code>&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for workflow data&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: PostgreSQL for workflow definitions and execution data&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: Database credentials from AWS Secrets Manager&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 512Mi (request), 2Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 250m (request), 1000m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for N8N data and files&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: Uses shared PostgreSQL cluster&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>N8N_HOST&lt;/code>&lt;/td>
&lt;td>&lt;code>n8n.landryzetam.net&lt;/code>&lt;/td>
&lt;td>External hostname&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_PORT&lt;/code>&lt;/td>
&lt;td>&lt;code>5678&lt;/code>&lt;/td>
&lt;td>Application port&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_PROTOCOL&lt;/code>&lt;/td>
&lt;td>&lt;code>https&lt;/code>&lt;/td>
&lt;td>External protocol&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>WEBHOOK_URL&lt;/code>&lt;/td>
&lt;td>&lt;code>https://n8n.landryzetam.net/&lt;/code>&lt;/td>
&lt;td>Webhook base URL&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>GENERIC_TIMEZONE&lt;/code>&lt;/td>
&lt;td>&lt;code>America/New_York&lt;/code>&lt;/td>
&lt;td>Timezone for scheduling&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_METRICS&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable metrics endpoint&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>N8N_TEMPLATES_ENABLED&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable workflow templates&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="database-configuration">Database Configuration&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Type&lt;/strong>: PostgreSQL&lt;/li>
&lt;li>&lt;strong>Host&lt;/strong>: &lt;code>postgres-cluster-rw.postgres.svc.cluster.local&lt;/code>&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: &lt;code>app&lt;/code>&lt;/li>
&lt;li>&lt;strong>User&lt;/strong>: &lt;code>app&lt;/code>&lt;/li>
&lt;li>&lt;strong>Password&lt;/strong>: Managed via External Secrets&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="accessing-n8n">Accessing N8N&lt;/h3>
&lt;p>External access:&lt;/p></description></item><item><title>GitOps in Practice: Managing k8s with FluxCD</title><link>https://blog.landryzetam.net/posts/gitops-with-fluxcd/</link><pubDate>Wed, 06 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/posts/gitops-with-fluxcd/</guid><description>&lt;p>After running the Fako Cluster for several months, I can confidently say that adopting GitOps with FluxCD has been one of the best decisions for managing my Kubernetes infrastructure. In this post, I&amp;rsquo;ll share practical insights and patterns that have proven invaluable.&lt;/p>
&lt;h2 id="what-is-gitops">What is GitOps?&lt;/h2>
&lt;p>GitOps is a way of implementing Continuous Deployment for cloud native applications.
FluxCD is designed to simplify that, making it easier than ever to manage your Kubernetes environments. Here’s why i leverage it in my workflow:&lt;/p></description></item><item><title>Second Brain</title><link>https://blog.landryzetam.net/secondbrain/</link><pubDate>Tue, 07 Jan 2025 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/secondbrain/</guid><description>&lt;figure>&lt;img src="https://blog.landryzetam.net/images/landry.png"
alt="Landry" width="150">
&lt;/figure>
&lt;h2 id="im-landry">I&amp;rsquo;m Landry.&lt;/h2>
&lt;p>I started as a mechanical engineer. Spent years thinking about how physical systems work: forces, tolerances, failure modes. Everything connected to everything else. Change one variable, watch the ripple effects cascade through the system. That way of thinking never left me.&lt;/p>
&lt;p>Then I moved into technical product management. Different domain, same principles. Instead of translating between physics and manufacturing, I was translating between business needs and technical teams. Requirements became architectures. Problems became roadmaps. I learned that the best solutions come from understanding both sides deeply: what people need and what systems can actually deliver.&lt;/p></description></item><item><title>Active Use Cases - Fako Cluster in Action</title><link>https://blog.landryzetam.net/pages/use-cases/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/use-cases/readme/</guid><description>&lt;p>This section documents real-world use cases and practical applications of the Fako cluster services. Each use case includes detailed walkthroughs, screenshots, and implementation details.&lt;/p>
&lt;h2 id="-table-of-contents">📋 Table of Contents&lt;/h2>
&lt;h3 id="aiml-use-cases">AI/ML Use Cases&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="#personal-ai-assistant">Personal AI Assistant&lt;/a>&lt;/li>
&lt;li>&lt;a href="#voice-controlled-home-automation">Voice-Controlled Home Automation&lt;/a>&lt;/li>
&lt;li>&lt;a href="#document-analysis-pipeline">Document Analysis Pipeline&lt;/a>&lt;/li>
&lt;li>&lt;a href="#multi-model-ai-comparison">Multi-Model AI Comparison&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="development--automation">Development &amp;amp; Automation&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="#gitops-workflow-management">GitOps Workflow Management&lt;/a>&lt;/li>
&lt;li>&lt;a href="#automated-security-scanning">Automated Security Scanning&lt;/a>&lt;/li>
&lt;li>&lt;a href="#cicd-pipeline-integration">CI/CD Pipeline Integration&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="personal-productivity">Personal Productivity&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="#health-data-analytics">Health Data Analytics&lt;/a>&lt;/li>
&lt;li>&lt;a href="#knowledge-management-system">Knowledge Management System&lt;/a>&lt;/li>
&lt;li>&lt;a href="#media-server-setup">Media Server Setup&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="infrastructure-management">Infrastructure Management&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="#multi-node-gpu-scheduling">Multi-Node GPU Scheduling&lt;/a>&lt;/li>
&lt;li>&lt;a href="#secure-remote-access">Secure Remote Access&lt;/a>&lt;/li>
&lt;li>&lt;a href="#automated-backup-strategy">Automated Backup Strategy&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="-personal-ai-assistant">🤖 Personal AI Assistant&lt;/h2>
&lt;h3 id="overview">Overview&lt;/h3>
&lt;p>A comprehensive AI assistant setup using Open WebUI, Ollama, and GPUStack for various AI models.&lt;/p></description></item><item><title>Audiobookshelf - Self-Hosted Audiobook and Podcast Server</title><link>https://blog.landryzetam.net/pages/services/audiobookshelf/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/audiobookshelf/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Audiobookshelf is a self-hosted audiobook and podcast server deployed in the Fako cluster. It provides a comprehensive media management system with features like automatic metadata fetching, progress syncing across devices, and a beautiful web interface. Audiobookshelf supports various audio formats and offers mobile apps for iOS and Android, making it a complete solution for managing and enjoying your audio library.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Multi-Format Support&lt;/strong>: MP3, M4A, M4B, FLAC, OGG, and more&lt;/li>
&lt;li>&lt;strong>Automatic Metadata&lt;/strong>: Fetches cover art, descriptions, and metadata&lt;/li>
&lt;li>&lt;strong>Progress Sync&lt;/strong>: Syncs playback position across all devices&lt;/li>
&lt;li>&lt;strong>Mobile Apps&lt;/strong>: Native iOS and Android applications&lt;/li>
&lt;li>&lt;strong>Multi-User&lt;/strong>: Support for multiple users with individual progress&lt;/li>
&lt;li>&lt;strong>Series Management&lt;/strong>: Organize books by series and authors&lt;/li>
&lt;li>&lt;strong>Podcast Support&lt;/strong>: Subscribe and manage podcast feeds&lt;/li>
&lt;li>&lt;strong>Sleep Timer&lt;/strong>: Built-in sleep timer for bedtime listening&lt;/li>
&lt;li>&lt;strong>Variable Playback Speed&lt;/strong>: Adjust playback speed to preference&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 3005&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Three PersistentVolumeClaims:
&lt;ul>
&lt;li>Config: Application configuration and database&lt;/li>
&lt;li>Metadata: Cover images and cached metadata&lt;/li>
&lt;li>Audiobooks: Media library storage&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Basic configuration settings&lt;/li>
&lt;li>&lt;strong>Security Context&lt;/strong>: Runs as user 1000&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 512Mi (request), 1Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 250m (request), 1000m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>:
&lt;ul>
&lt;li>Config volume for database&lt;/li>
&lt;li>Metadata volume for images/cache&lt;/li>
&lt;li>Audiobooks volume for media files&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="deployment-settings">Deployment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Image&lt;/td>
&lt;td>&lt;code>ghcr.io/advplyr/audiobookshelf:2.26.0&lt;/code>&lt;/td>
&lt;td>Audiobookshelf version&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Port&lt;/td>
&lt;td>&lt;code>3005&lt;/code>&lt;/td>
&lt;td>Web interface port&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>User/Group&lt;/td>
&lt;td>&lt;code>1000&lt;/code>&lt;/td>
&lt;td>Non-root user&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Volumes&lt;/td>
&lt;td>3 mounts&lt;/td>
&lt;td>Config, metadata, and media&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="volume-mounts">Volume Mounts&lt;/h3>
&lt;ul>
&lt;li>&lt;code>/config&lt;/code>: Database and configuration files&lt;/li>
&lt;li>&lt;code>/metadata&lt;/code>: Cover art and metadata cache&lt;/li>
&lt;li>&lt;code>/audiobooks&lt;/code>: Media library root directory&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="accessing-audiobookshelf">Accessing Audiobookshelf&lt;/h3>
&lt;p>Internal access:&lt;/p></description></item><item><title>Gitleaks - Secret Detection and Cleanup Service</title><link>https://blog.landryzetam.net/pages/services/gitleaks/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/gitleaks/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Gitleaks is an automated secret scanning and cleanup service deployed in the Fako cluster. It runs as a scheduled CronJob that scans Git repositories for exposed secrets, API keys, and sensitive information. When secrets are detected, it can automatically remove them from the entire Git history using BFG Repo-Cleaner. This service helps maintain security by preventing accidental exposure of credentials in version control.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Automated Scanning&lt;/strong>: Scheduled scans every 6 hours&lt;/li>
&lt;li>&lt;strong>Secret Detection&lt;/strong>: Identifies various types of secrets and credentials&lt;/li>
&lt;li>&lt;strong>History Cleanup&lt;/strong>: Removes secrets from entire Git history&lt;/li>
&lt;li>&lt;strong>Dry Run Mode&lt;/strong>: Test scans without making changes&lt;/li>
&lt;li>&lt;strong>Auto-Push&lt;/strong>: Optional automatic pushing of cleaned repos&lt;/li>
&lt;li>&lt;strong>Slack Notifications&lt;/strong>: Alerts when secrets are found&lt;/li>
&lt;li>&lt;strong>GitHub Integration&lt;/strong>: Uses GitHub token for authentication&lt;/li>
&lt;li>&lt;strong>Comprehensive Reports&lt;/strong>: JSON reports of findings&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>CronJob&lt;/strong>: Scheduled execution every 6 hours&lt;/li>
&lt;li>&lt;strong>ServiceAccount&lt;/strong>: For Kubernetes API access&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Cleanup script and configuration&lt;/li>
&lt;li>&lt;strong>External Secret&lt;/strong>: GitHub token from AWS Secrets Manager&lt;/li>
&lt;li>&lt;strong>Init Container&lt;/strong>: Installs required tools (BFG, Java)&lt;/li>
&lt;li>&lt;strong>Volumes&lt;/strong>: Temporary storage for scans and results&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 512Mi (request), 1Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 200m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: EmptyDir volumes for temporary data&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-variables">Environment Variables&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Variable&lt;/th>
&lt;th>Default&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>GITHUB_TOKEN&lt;/code>&lt;/td>
&lt;td>From secret&lt;/td>
&lt;td>GitHub authentication token&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>DRY_RUN&lt;/code>&lt;/td>
&lt;td>&lt;code>false&lt;/code>&lt;/td>
&lt;td>Run scan without cleanup&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>AUTO_PUSH&lt;/code>&lt;/td>
&lt;td>&lt;code>false&lt;/code>&lt;/td>
&lt;td>Auto-push cleaned repos&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>SLACK_WEBHOOK&lt;/code>&lt;/td>
&lt;td>Optional&lt;/td>
&lt;td>Slack notification URL&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>REPO_URL&lt;/code>&lt;/td>
&lt;td>In script&lt;/td>
&lt;td>Target repository URL&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="schedule">Schedule&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>CronJob Schedule&lt;/strong>: &lt;code>0 */6 * * *&lt;/code> (every 6 hours)&lt;/li>
&lt;li>Runs at: 00:00, 06:00, 12:00, 18:00 UTC&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="manual-execution">Manual Execution&lt;/h3>
&lt;p>Trigger a manual scan:&lt;/p></description></item><item><title>GPUStack Proxy - Secure Tunnel Access Service</title><link>https://blog.landryzetam.net/pages/services/gpustack-proxy/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/gpustack-proxy/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>GPUStack Proxy is a Cloudflare Tunnel-based proxy service deployed in the Fako cluster that provides secure external access to the GPUStack AI inference platform. It uses Cloudflare&amp;rsquo;s cloudflared to create an encrypted tunnel between the cluster and Cloudflare&amp;rsquo;s edge network, eliminating the need for exposed public IPs or open inbound ports. The service includes automatic endpoint synchronization with AWS Secrets Manager for seamless integration with AI applications.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Cloudflare Tunnel&lt;/strong>: Zero-trust secure access without exposed ports&lt;/li>
&lt;li>&lt;strong>High Availability&lt;/strong>: Multi-replica cloudflared deployment&lt;/li>
&lt;li>&lt;strong>Automatic Failover&lt;/strong>: Built-in redundancy and health checks&lt;/li>
&lt;li>&lt;strong>Endpoint Sync&lt;/strong>: Automated endpoint updates to AWS Secrets Manager&lt;/li>
&lt;li>&lt;strong>SSL/TLS Termination&lt;/strong>: Handled by Cloudflare edge&lt;/li>
&lt;li>&lt;strong>DDoS Protection&lt;/strong>: Cloudflare&amp;rsquo;s built-in protection&lt;/li>
&lt;li>&lt;strong>No Public IP Required&lt;/strong>: Works behind NAT/firewall&lt;/li>
&lt;li>&lt;strong>Metrics &amp;amp; Monitoring&lt;/strong>: Built-in metrics endpoint&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Cloudflared Deployment&lt;/strong>: 2 replicas for HA&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP routing to GPUStack&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Tunnel configuration&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: Tunnel credentials from AWS&lt;/li>
&lt;li>&lt;strong>Endpoint Sync Job&lt;/strong>: Updates AWS with tunnel info&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: Optional Kubernetes ingress&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 128Mi (request), 256Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 250m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Replicas&lt;/strong>: 2 for high availability&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="tunnel-configuration">Tunnel Configuration&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Tunnel Name&lt;/td>
&lt;td>&lt;code>audiobooks&lt;/code>&lt;/td>
&lt;td>Cloudflare tunnel identifier&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Hostname&lt;/td>
&lt;td>&lt;code>gpustack.landryzetam.net&lt;/code>&lt;/td>
&lt;td>External access URL&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Target&lt;/td>
&lt;td>&lt;code>http://gpustack:80&lt;/code>&lt;/td>
&lt;td>Internal GPUStack service&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Metrics Port&lt;/td>
&lt;td>&lt;code>2000&lt;/code>&lt;/td>
&lt;td>Health and metrics endpoint&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="service-routing">Service Routing&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">ingress&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">hostname&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gpustack.landryzetam.net&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">service&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">http://gpustack:80&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">hostname&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">hello.example.com&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">service&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">hello_world &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Debug endpoint&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">service&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">http_status:404 &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Catch-all&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="accessing-gpustack">Accessing GPUStack&lt;/h3>
&lt;p>External access via Cloudflare:&lt;/p></description></item><item><title>Headlamp - Kubernetes Dashboard</title><link>https://blog.landryzetam.net/pages/services/headlamp/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/headlamp/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Headlamp is a user-friendly Kubernetes dashboard deployed in the Fako cluster. It provides a web-based UI for managing and monitoring Kubernetes resources across all namespaces. Headlamp offers an intuitive interface for both beginners and advanced users, with support for plugins and real-time updates. This deployment includes the Kubescape security plugin for enhanced cluster security visibility.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>User-Friendly Interface&lt;/strong>: Clean, modern UI for Kubernetes management&lt;/li>
&lt;li>&lt;strong>Real-Time Updates&lt;/strong>: Live view of cluster resources and events&lt;/li>
&lt;li>&lt;strong>Multi-Resource Support&lt;/strong>: Manage all Kubernetes resource types&lt;/li>
&lt;li>&lt;strong>Plugin Architecture&lt;/strong>: Extensible with custom plugins&lt;/li>
&lt;li>&lt;strong>In-Cluster Mode&lt;/strong>: Runs with cluster service account&lt;/li>
&lt;li>&lt;strong>Kubescape Integration&lt;/strong>: Security scanning and compliance checks&lt;/li>
&lt;li>&lt;strong>Mobile Responsive&lt;/strong>: Works on desktop and mobile devices&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 80&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access (configured separately)&lt;/li>
&lt;li>&lt;strong>ServiceAccount&lt;/strong>: Cluster-wide permissions for resource access&lt;/li>
&lt;li>&lt;strong>Init Container&lt;/strong>: Installs Kubescape plugin&lt;/li>
&lt;li>&lt;strong>Plugin Volume&lt;/strong>: EmptyDir for plugin storage&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 128Mi (request), 512Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 100m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: EmptyDir for plugins (ephemeral)&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="deployment-settings">Deployment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>-in-cluster&lt;/code>&lt;/td>
&lt;td>Enabled&lt;/td>
&lt;td>Run using in-cluster config&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>-plugins-dir&lt;/code>&lt;/td>
&lt;td>&lt;code>/build/plugins&lt;/code>&lt;/td>
&lt;td>Plugin directory location&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Port&lt;/td>
&lt;td>&lt;code>4466&lt;/code>&lt;/td>
&lt;td>Application HTTP port&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Image&lt;/td>
&lt;td>&lt;code>ghcr.io/headlamp-k8s/headlamp:v0.33.0&lt;/code>&lt;/td>
&lt;td>Headlamp version&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="rbac-configuration">RBAC Configuration&lt;/h3>
&lt;p>Headlamp runs with a ClusterRole that provides full access to:&lt;/p></description></item><item><title>Housekeeping - Cluster Cleanup Service</title><link>https://blog.landryzetam.net/pages/services/housekeeping/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/housekeeping/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Housekeeping is an automated cluster maintenance service deployed in the Fako cluster. It runs as a CronJob that periodically cleans up completed and failed pods across all namespaces. This service helps maintain cluster hygiene by removing terminated pods that would otherwise accumulate and consume resources. It&amp;rsquo;s essential for keeping the cluster clean and preventing resource exhaustion from leftover pod metadata.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Automated Cleanup&lt;/strong>: Runs every hour to clean terminated pods&lt;/li>
&lt;li>&lt;strong>Cluster-Wide&lt;/strong>: Scans all namespaces for cleanup candidates&lt;/li>
&lt;li>&lt;strong>Safe Deletion&lt;/strong>: Only removes pods in Succeeded or Failed states&lt;/li>
&lt;li>&lt;strong>Detailed Logging&lt;/strong>: Reports what was found and cleaned&lt;/li>
&lt;li>&lt;strong>Concurrency Control&lt;/strong>: Prevents overlapping cleanup runs&lt;/li>
&lt;li>&lt;strong>Statistics Tracking&lt;/strong>: Counts total pods found and deleted&lt;/li>
&lt;li>&lt;strong>Force Deletion&lt;/strong>: Uses grace period 0 for immediate removal&lt;/li>
&lt;li>&lt;strong>Job History&lt;/strong>: Keeps history of last 3 successful/failed runs&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>CronJob&lt;/strong>: Scheduled execution every hour&lt;/li>
&lt;li>&lt;strong>ServiceAccount&lt;/strong>: Cluster-wide permissions for pod management&lt;/li>
&lt;li>&lt;strong>ClusterRole&lt;/strong>: Permissions to list and delete pods&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Cleanup script with logic&lt;/li>
&lt;li>&lt;strong>Container&lt;/strong>: kubectl image with bash script execution&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Image&lt;/strong>: &lt;code>bitnami/kubectl:1.33&lt;/code>&lt;/li>
&lt;li>&lt;strong>CPU/Memory&lt;/strong>: Minimal (kubectl operations)&lt;/li>
&lt;li>&lt;strong>Permissions&lt;/strong>: Cluster-wide pod list/delete&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="schedule">Schedule&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>CronJob Schedule&lt;/strong>: &lt;code>0 * * * *&lt;/code> (every hour at minute 0)&lt;/li>
&lt;li>&lt;strong>Concurrency Policy&lt;/strong>: &lt;code>Forbid&lt;/code> (no overlapping runs)&lt;/li>
&lt;li>&lt;strong>TTL After Finish&lt;/strong>: 3600 seconds (1 hour)&lt;/li>
&lt;li>&lt;strong>History Limits&lt;/strong>: 3 successful, 3 failed jobs&lt;/li>
&lt;/ul>
&lt;h3 id="cleanup-targets">Cleanup Targets&lt;/h3>
&lt;p>The service removes pods in these states:&lt;/p></description></item><item><title>How to Document Your Fako Cluster Setup</title><link>https://blog.landryzetam.net/pages/guides/documenting-your-setup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/guides/documenting-your-setup/</guid><description>&lt;p>This guide will help you systematically document all aspects of your Fako cluster using the Hugo blog system.&lt;/p>
&lt;h2 id="overview-of-the-documentation-system">Overview of the Documentation System&lt;/h2>
&lt;p>Your documentation system consists of:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Central docs directory&lt;/strong>: &lt;code>/docs/&lt;/code> in your repository&lt;/li>
&lt;li>&lt;strong>Hugo blog&lt;/strong>: Automatically syncs and serves documentation&lt;/li>
&lt;li>&lt;strong>CronJob&lt;/strong>: Updates the blog every 6 hours from GitHub&lt;/li>
&lt;/ol>
&lt;h2 id="step-by-step-documentation-process">Step-by-Step Documentation Process&lt;/h2>
&lt;h3 id="1-document-your-services">1. Document Your Services&lt;/h3>
&lt;p>For each service in &lt;code>apps/base/&lt;/code>, create documentation using the template:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Copy the template&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cp docs/services/SERVICE_TEMPLATE.md docs/services/&lt;span class="o">[&lt;/span>service-name&lt;span class="o">]&lt;/span>/README.md
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Edit with your service details&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Priority services to document:&lt;/p></description></item><item><title>Hugo Blog Documentation Service</title><link>https://blog.landryzetam.net/pages/services/blog/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/blog/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>The Hugo Blog service is a static site generator that serves as the central documentation hub for the Fako cluster. It automatically collects and organizes documentation from across the repository, presenting it in a searchable, user-friendly website. The service uses Hugo with automatic synchronization from GitHub.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Automatic Documentation Collection&lt;/strong>: CronJob syncs docs every 6 hours&lt;/li>
&lt;li>&lt;strong>Static Site Generation&lt;/strong>: Fast, secure Hugo-based site&lt;/li>
&lt;li>&lt;strong>GitHub Integration&lt;/strong>: Pulls documentation directly from repository&lt;/li>
&lt;li>&lt;strong>Organized Structure&lt;/strong>: Categorized documentation (services, guides, architecture)&lt;/li>
&lt;li>&lt;strong>Minimal Deployment&lt;/strong>: Simple Hugo server with basic theme&lt;/li>
&lt;li>&lt;strong>Persistent Storage&lt;/strong>: Documentation cached in PVC&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica Hugo server deployment&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 80&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access at &lt;code>blog.fako-cluster.local&lt;/code>&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: 5Gi PersistentVolumeClaim for content&lt;/li>
&lt;li>&lt;strong>ConfigMaps&lt;/strong>:
&lt;ul>
&lt;li>Documentation copy scripts&lt;/li>
&lt;li>Hugo configuration (if customized)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>CronJob&lt;/strong>: Automatic GitHub synchronization&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 128Mi (request), 256Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 100m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: 5Gi for Hugo site content&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="hugo-server-configuration">Hugo Server Configuration&lt;/h3>
&lt;p>The deployment creates a minimal Hugo site on startup with:&lt;/p></description></item><item><title>Infrastructure Documentation</title><link>https://blog.landryzetam.net/pages/infrastructure/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/infrastructure/readme/</guid><description>&lt;h2 id="-this-content-has-been-reorganized">📍 This content has been reorganized!&lt;/h2>
&lt;p>The infrastructure documentation has been consolidated into the &lt;strong>Kubernetes (K8s) project&lt;/strong>, which is the foundation of our entire platform.&lt;/p>
&lt;h3 id="-please-visit-the-kubernetes-k8s-project-for">🏗️ Please visit the &lt;a href="https://blog.landryzetam.net/pages/projects/k8s/">Kubernetes (K8s) Project&lt;/a> for:&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://blog.landryzetam.net/pages/projects/k8s/architecture">Architecture&lt;/a>&lt;/strong> - High-level system design and principles&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://blog.landryzetam.net/pages/projects/k8s/infrastructure">Infrastructure&lt;/a>&lt;/strong> - Core components and configurations&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://blog.landryzetam.net/pages/projects/k8s/operations">Operations&lt;/a>&lt;/strong> - Maintenance procedures and runbooks&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://blog.landryzetam.net/pages/projects/k8s/security">Security&lt;/a>&lt;/strong> - Security architecture and practices&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://blog.landryzetam.net/pages/projects/k8s/networking">Networking&lt;/a>&lt;/strong> - Network setup and ingress management&lt;/li>
&lt;li>&lt;strong>&lt;a href="https://blog.landryzetam.net/pages/projects/k8s/storage">Storage&lt;/a>&lt;/strong> - Persistent storage solutions&lt;/li>
&lt;/ul>
&lt;h2 id="why-the-change">Why the Change?&lt;/h2>
&lt;p>We&amp;rsquo;ve reorganized our documentation to better reflect that Kubernetes is the foundation upon which all other services are built. This makes it clearer that:&lt;/p></description></item><item><title>KAgent - Kubernetes AI Agent Framework</title><link>https://blog.landryzetam.net/pages/services/kagent/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/kagent/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>KAgent is a Kubernetes-native AI agent framework deployed in the Fako cluster. It provides a platform for deploying and managing AI agents that can interact with various systems through the Model Context Protocol (MCP). Agents can be configured with different AI models, specialized knowledge, and tool access. The framework supports multiple AI providers including OpenAI, Ollama, and GPUStack, making it flexible for various use cases from Kubernetes operations to code generation.&lt;/p></description></item><item><title>Keycloak - Identity and Access Management</title><link>https://blog.landryzetam.net/pages/services/keycloak/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/keycloak/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Keycloak is an open-source Identity and Access Management (IAM) solution deployed in the Fako cluster. It provides single sign-on (SSO), user federation, identity brokering, and social login capabilities. This deployment uses Keycloak 26.x with PostgreSQL backend and is configured for high availability with clustering.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Single Sign-On (SSO)&lt;/strong>: One login for multiple applications&lt;/li>
&lt;li>&lt;strong>Identity Brokering&lt;/strong>: Connect to external identity providers&lt;/li>
&lt;li>&lt;strong>User Federation&lt;/strong>: Sync users from LDAP or Active Directory&lt;/li>
&lt;li>&lt;strong>Social Login&lt;/strong>: Support for Google, GitHub, Facebook, etc.&lt;/li>
&lt;li>&lt;strong>Multi-Factor Authentication&lt;/strong>: Enhanced security with MFA&lt;/li>
&lt;li>&lt;strong>High Availability&lt;/strong>: Clustered deployment with 2 replicas&lt;/li>
&lt;li>&lt;strong>Secure Credential Management&lt;/strong>: Integration with AWS Secrets Manager&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: 2-replica deployment with pod anti-affinity&lt;/li>
&lt;li>&lt;strong>Services&lt;/strong>:
&lt;ul>
&lt;li>Main service on port 8080&lt;/li>
&lt;li>Headless service for JGroups clustering&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PostgreSQL database (postgres-cluster)&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Environment configuration&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>:
&lt;ul>
&lt;li>Admin credentials from AWS Secrets Manager&lt;/li>
&lt;li>Database credentials from AWS Secrets Manager&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Init Container&lt;/strong>: Database initialization and user setup&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 1Gi (request), 2Gi (limit) per pod&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 500m (request), 1000m (limit) per pod&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: PostgreSQL with dedicated database and user&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>KC_HOSTNAME&lt;/code>&lt;/td>
&lt;td>&lt;code>https://auth.landryzetam.net&lt;/code>&lt;/td>
&lt;td>External hostname&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_HOSTNAME_STRICT&lt;/code>&lt;/td>
&lt;td>&lt;code>false&lt;/code>&lt;/td>
&lt;td>Allow backend access&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_HTTP_ENABLED&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable HTTP (behind proxy)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_PROXY&lt;/code>&lt;/td>
&lt;td>&lt;code>edge&lt;/code>&lt;/td>
&lt;td>Running behind edge proxy&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_PROXY_HEADERS&lt;/code>&lt;/td>
&lt;td>&lt;code>xforwarded&lt;/code>&lt;/td>
&lt;td>Use X-Forwarded headers&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_HEALTH_ENABLED&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable health endpoints&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_METRICS_ENABLED&lt;/code>&lt;/td>
&lt;td>&lt;code>true&lt;/code>&lt;/td>
&lt;td>Enable metrics&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>KC_CACHE_STACK&lt;/code>&lt;/td>
&lt;td>&lt;code>kubernetes&lt;/code>&lt;/td>
&lt;td>Use Kubernetes discovery&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="database-configuration">Database Configuration&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Type&lt;/strong>: PostgreSQL&lt;/li>
&lt;li>&lt;strong>Host&lt;/strong>: &lt;code>postgres-cluster-rw.postgres.svc.cluster.local&lt;/code>&lt;/li>
&lt;li>&lt;strong>Port&lt;/strong>: 5432&lt;/li>
&lt;li>&lt;strong>Database&lt;/strong>: &lt;code>keycloak&lt;/code>&lt;/li>
&lt;li>&lt;strong>Credentials&lt;/strong>: Managed via AWS Secrets Manager&lt;/li>
&lt;/ul>
&lt;h3 id="clustering-configuration">Clustering Configuration&lt;/h3>
&lt;p>JGroups clustering is configured for session replication:&lt;/p></description></item><item><title>Kube-bench - Kubernetes Security Benchmark Scanner</title><link>https://blog.landryzetam.net/pages/services/kube-bench/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/kube-bench/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Kube-bench is an automated security compliance scanner deployed in the Fako cluster. It runs the CIS Kubernetes Benchmark checks to ensure the cluster follows security best practices. The service executes as a daily CronJob that performs comprehensive security scans, checking configurations of various Kubernetes components against industry standards. Results are saved with timestamps for audit trails and compliance reporting.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>CIS Benchmark Compliance&lt;/strong>: Checks against Center for Internet Security standards&lt;/li>
&lt;li>&lt;strong>Automated Scanning&lt;/strong>: Daily scheduled security assessments&lt;/li>
&lt;li>&lt;strong>Comprehensive Coverage&lt;/strong>: Scans master and worker node configurations&lt;/li>
&lt;li>&lt;strong>JSON Output&lt;/strong>: Machine-readable results for integration&lt;/li>
&lt;li>&lt;strong>Historical Records&lt;/strong>: Timestamped results for trend analysis&lt;/li>
&lt;li>&lt;strong>Host Access&lt;/strong>: Direct access to Kubernetes configuration files&lt;/li>
&lt;li>&lt;strong>Multi-Component&lt;/strong>: Checks etcd, kubelet, API server, and more&lt;/li>
&lt;li>&lt;strong>Results Processing&lt;/strong>: Automatic display of scan findings&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>CronJob&lt;/strong>: Daily execution at 2 AM&lt;/li>
&lt;li>&lt;strong>ServiceAccount&lt;/strong>: Permissions for scanning operations&lt;/li>
&lt;li>&lt;strong>Main Container&lt;/strong>: kube-bench scanner with host access&lt;/li>
&lt;li>&lt;strong>Results Processor&lt;/strong>: Monitors and displays scan results&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for scan history&lt;/li>
&lt;li>&lt;strong>Host Mounts&lt;/strong>: Access to Kubernetes system directories&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Scanner&lt;/strong>: 256Mi RAM (request), 512Mi (limit)&lt;/li>
&lt;li>&lt;strong>Processor&lt;/strong>: 64Mi RAM (request), 128Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 100m-300m for scanner, 50m-100m for processor&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for results history&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="schedule">Schedule&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>CronJob Schedule&lt;/strong>: &lt;code>0 2 * * *&lt;/code> (daily at 2:00 AM)&lt;/li>
&lt;li>&lt;strong>Concurrency Policy&lt;/strong>: &lt;code>Forbid&lt;/code> (no overlapping scans)&lt;/li>
&lt;li>&lt;strong>History Limits&lt;/strong>: 3 successful, 3 failed jobs&lt;/li>
&lt;/ul>
&lt;h3 id="security-context">Security Context&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>hostPID&lt;/strong>: &lt;code>true&lt;/code> (access host processes)&lt;/li>
&lt;li>&lt;strong>privileged&lt;/strong>: &lt;code>true&lt;/code> (full host access)&lt;/li>
&lt;li>&lt;strong>Read-only mounts&lt;/strong>: All host paths mounted read-only&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="manual-scan-execution">Manual Scan Execution&lt;/h3>
&lt;p>Trigger an immediate security scan:&lt;/p></description></item><item><title>Kubescape Operator - Kubernetes Security Scanning Platform</title><link>https://blog.landryzetam.net/pages/services/kubescape-operator/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/kubescape-operator/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Kubescape Operator is a comprehensive Kubernetes security scanning platform deployed in the Fako cluster. It provides continuous security assessment using multiple frameworks including NSA, MITRE, and CIS benchmarks. The operator performs real-time vulnerability scanning, compliance checking, and network policy analysis. It stores scan results locally and can optionally integrate with Kubescape Cloud for enhanced dashboards and reporting.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Multi-Framework Scanning&lt;/strong>: NSA, MITRE, CIS compliance checks&lt;/li>
&lt;li>&lt;strong>Continuous Monitoring&lt;/strong>: Real-time security posture assessment&lt;/li>
&lt;li>&lt;strong>Vulnerability Scanning&lt;/strong>: Container image vulnerability detection&lt;/li>
&lt;li>&lt;strong>Network Policy Analysis&lt;/strong>: Automated network policy recommendations&lt;/li>
&lt;li>&lt;strong>Local Storage&lt;/strong>: Persistent storage for scan results and vulnerability DB&lt;/li>
&lt;li>&lt;strong>Prometheus Metrics&lt;/strong>: Export security metrics for monitoring&lt;/li>
&lt;li>&lt;strong>Node Agent&lt;/strong>: Runtime security monitoring on Linux nodes&lt;/li>
&lt;li>&lt;strong>Scheduled Scans&lt;/strong>: Configurable scanning intervals&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Operator&lt;/strong>: Core controller managing scans&lt;/li>
&lt;li>&lt;strong>Kubevuln&lt;/strong>: Vulnerability scanner component&lt;/li>
&lt;li>&lt;strong>Gateway&lt;/strong>: API gateway for results&lt;/li>
&lt;li>&lt;strong>Node Agent&lt;/strong>: Runtime security on each node&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: NFS-backed persistent volumes&lt;/li>
&lt;li>&lt;strong>Helm Release&lt;/strong>: Managed by Flux&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Component&lt;/th>
&lt;th>Memory Request&lt;/th>
&lt;th>Memory Limit&lt;/th>
&lt;th>CPU Request&lt;/th>
&lt;th>CPU Limit&lt;/th>
&lt;th>Ephemeral Storage&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Operator&lt;/td>
&lt;td>256Mi&lt;/td>
&lt;td>512Mi&lt;/td>
&lt;td>100m&lt;/td>
&lt;td>500m&lt;/td>
&lt;td>1Gi/2Gi&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Kubevuln&lt;/td>
&lt;td>512Mi&lt;/td>
&lt;td>1Gi&lt;/td>
&lt;td>200m&lt;/td>
&lt;td>500m&lt;/td>
&lt;td>5Gi/15Gi&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Gateway&lt;/td>
&lt;td>256Mi&lt;/td>
&lt;td>512Mi&lt;/td>
&lt;td>100m&lt;/td>
&lt;td>300m&lt;/td>
&lt;td>1Gi/2Gi&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="scanning-schedule">Scanning Schedule&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Framework&lt;/th>
&lt;th>Schedule&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>NSA&lt;/td>
&lt;td>Every 6 hours&lt;/td>
&lt;td>National Security Agency guidelines&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>MITRE&lt;/td>
&lt;td>Every 6 hours&lt;/td>
&lt;td>MITRE ATT&amp;amp;CK framework&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>CIS v1.23&lt;/td>
&lt;td>Daily at 2 AM&lt;/td>
&lt;td>Center for Internet Security benchmark&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="storage-configuration">Storage Configuration&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Scan Results&lt;/strong>: 20Gi on &lt;code>nfs-security-logs&lt;/code>&lt;/li>
&lt;li>&lt;strong>Vulnerability DB&lt;/strong>: 10Gi on &lt;code>nfs-security-logs&lt;/code>&lt;/li>
&lt;li>&lt;strong>Access Mode&lt;/strong>: ReadWriteOnce&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="viewing-scan-results">Viewing Scan Results&lt;/h3>
&lt;p>Access scan results via kubectl:&lt;/p></description></item><item><title>Linkding - Self-Hosted Bookmark Manager</title><link>https://blog.landryzetam.net/pages/services/linkding/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/linkding/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Linkding is a self-hosted bookmark manager deployed in the Fako cluster. It provides a clean, minimal web interface for saving, organizing, and searching bookmarks. Linkding offers features like automatic title and description retrieval, tagging, full-text search, and bookmark archiving. It&amp;rsquo;s designed as a privacy-focused alternative to commercial bookmark services, keeping all your data under your control.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Privacy-Focused&lt;/strong>: Self-hosted with no external dependencies&lt;/li>
&lt;li>&lt;strong>Clean Interface&lt;/strong>: Minimalist, fast web UI&lt;/li>
&lt;li>&lt;strong>Tagging System&lt;/strong>: Organize bookmarks with tags&lt;/li>
&lt;li>&lt;strong>Full-Text Search&lt;/strong>: Search titles, descriptions, and tags&lt;/li>
&lt;li>&lt;strong>Auto-Completion&lt;/strong>: Title and description fetching&lt;/li>
&lt;li>&lt;strong>Archive Support&lt;/strong>: Archive bookmarks with Wayback Machine&lt;/li>
&lt;li>&lt;strong>Import/Export&lt;/strong>: Supports standard bookmark formats&lt;/li>
&lt;li>&lt;strong>REST API&lt;/strong>: Programmatic access to bookmarks&lt;/li>
&lt;li>&lt;strong>Mobile-Friendly&lt;/strong>: Responsive design for all devices&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 9090&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for bookmark data&lt;/li>
&lt;li>&lt;strong>Secret&lt;/strong>: Environment variables for configuration&lt;/li>
&lt;li>&lt;strong>Security Context&lt;/strong>: Runs as www-data user (UID 33)&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 128Mi (request), 256Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 250m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for database and assets&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="deployment-settings">Deployment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Image&lt;/td>
&lt;td>&lt;code>sissbruecker/linkding:1.41.0&lt;/code>&lt;/td>
&lt;td>Linkding version&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Port&lt;/td>
&lt;td>&lt;code>9090&lt;/code>&lt;/td>
&lt;td>Web interface port&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>User&lt;/td>
&lt;td>&lt;code>www-data (33)&lt;/code>&lt;/td>
&lt;td>Run as non-root user&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Data Path&lt;/td>
&lt;td>&lt;code>/etc/linkding/data&lt;/code>&lt;/td>
&lt;td>Persistent data location&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="environment-variables">Environment Variables&lt;/h3>
&lt;p>Configuration via &lt;code>linkding-container-env&lt;/code> secret:&lt;/p></description></item><item><title>MCP Servers - Model Context Protocol Services</title><link>https://blog.landryzetam.net/pages/services/mcp-servers/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/mcp-servers/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>MCP (Model Context Protocol) Servers is a collection of specialized services deployed in the Fako cluster that extend AI capabilities by providing structured access to various tools and resources. These servers implement the Model Context Protocol, enabling AI assistants like Claude to interact with external systems, databases, APIs, and tools in a standardized way. Each MCP server provides specific functionality that can be consumed by AI agents for enhanced automation and integration.&lt;/p></description></item><item><title>Node Labeling - Kubernetes Node Classification Service</title><link>https://blog.landryzetam.net/pages/services/node-labeling/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/node-labeling/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Node Labeling is an automated Kubernetes job deployed in the Fako cluster that applies strategic labels to cluster nodes. It classifies nodes based on their hardware capabilities, particularly focusing on GPU resources and performance tiers. This service ensures that workloads can be properly scheduled to appropriate nodes using node selectors and affinity rules. The labeling is crucial for GPU workloads, voice pipeline services, and general workload distribution across the heterogeneous cluster.&lt;/p></description></item><item><title>Ollama WebUI - Test Instance of Open WebUI</title><link>https://blog.landryzetam.net/pages/services/ollama-webui/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/ollama-webui/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Ollama WebUI is a test/staging deployment of Open WebUI in the Fako cluster. Despite its name, this service actually uses the Open WebUI image and is configured to connect to GPUStack (not Ollama) as its AI backend. It serves as a testing environment for new configurations, model testing, and user onboarding before changes are promoted to the production Open WebUI instance. This separation allows for safe experimentation without affecting production users.&lt;/p></description></item><item><title>OpenWakeWord - Wake Word Detection Service</title><link>https://blog.landryzetam.net/pages/services/openwakeword/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/openwakeword/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>OpenWakeWord is a wake word detection service deployed in the Fako cluster as part of the voice assistant pipeline. It uses machine learning models to detect specific wake words (like &amp;ldquo;Hey Jarvis&amp;rdquo;) in continuous audio streams. The service implements the Wyoming protocol for integration with voice assistants and can handle multiple concurrent audio streams. It&amp;rsquo;s designed for low-latency, real-time wake word detection and scales automatically based on load.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Real-Time Detection&lt;/strong>: Low-latency wake word detection&lt;/li>
&lt;li>&lt;strong>Multiple Models&lt;/strong>: Support for various wake word models&lt;/li>
&lt;li>&lt;strong>Wyoming Protocol&lt;/strong>: Standard voice assistant integration&lt;/li>
&lt;li>&lt;strong>Auto-Scaling&lt;/strong>: HPA-based scaling for concurrent streams&lt;/li>
&lt;li>&lt;strong>Model Preloading&lt;/strong>: Fast startup with preloaded models&lt;/li>
&lt;li>&lt;strong>High Performance&lt;/strong>: Optimized for CPU-based inference&lt;/li>
&lt;li>&lt;strong>Debug Mode&lt;/strong>: Detailed logging for troubleshooting&lt;/li>
&lt;li>&lt;strong>Health Monitoring&lt;/strong>: TCP-based health checks&lt;/li>
&lt;li>&lt;strong>Persistent Storage&lt;/strong>: Model caching and custom models&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single to multi-replica with HPA&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP on port 10400&lt;/li>
&lt;li>&lt;strong>NodePort Service&lt;/strong>: Optional external access&lt;/li>
&lt;li>&lt;strong>HPA&lt;/strong>: Auto-scaling 1-3 replicas&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PVC for model storage&lt;/li>
&lt;li>&lt;strong>Node Affinity&lt;/strong>: Avoids control plane nodes&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 2Gi (request), 3Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 2 cores (request), 3 cores (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for models&lt;/li>
&lt;li>&lt;strong>Scaling&lt;/strong>: Up to 3 replicas for 4+ streams&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="service-settings">Service Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>Port&lt;/td>
&lt;td>&lt;code>10400&lt;/code>&lt;/td>
&lt;td>Wyoming protocol port&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Protocol&lt;/td>
&lt;td>&lt;code>TCP&lt;/code>&lt;/td>
&lt;td>Wyoming TCP transport&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Preloaded Model&lt;/td>
&lt;td>&lt;code>hey_jarvis&lt;/code>&lt;/td>
&lt;td>Default wake word&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Debug&lt;/td>
&lt;td>Enabled&lt;/td>
&lt;td>Verbose logging&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="auto-scaling-configuration">Auto-Scaling Configuration&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Min Replicas&lt;/strong>: 1&lt;/li>
&lt;li>&lt;strong>Max Replicas&lt;/strong>: 3&lt;/li>
&lt;li>&lt;strong>CPU Target&lt;/strong>: 50% utilization&lt;/li>
&lt;li>&lt;strong>Memory Target&lt;/strong>: 60% utilization&lt;/li>
&lt;li>&lt;strong>Scale Up&lt;/strong>: 15 seconds stabilization&lt;/li>
&lt;li>&lt;strong>Scale Down&lt;/strong>: 300 seconds stabilization&lt;/li>
&lt;/ul>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="wyoming-protocol-access">Wyoming Protocol Access&lt;/h3>
&lt;p>Internal service:&lt;/p></description></item><item><title>Oura Collector - Health Data Collection Service</title><link>https://blog.landryzetam.net/pages/services/oura-collector/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/oura-collector/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Oura Collector is an automated health data collection service deployed in the Fako cluster. It integrates with the Oura Ring API to collect personal health metrics including sleep, activity, readiness, and heart rate data. The service stores this data in PostgreSQL for analysis and visualization. It features scheduled collection, backfill capabilities, and secure credential management through AWS Secrets Manager. This enables long-term health tracking and analysis within your personal infrastructure.&lt;/p></description></item><item><title>pgAdmin - PostgreSQL Management Tool</title><link>https://blog.landryzetam.net/pages/services/pgadmin/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/pgadmin/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>pgAdmin is a comprehensive web-based management tool for PostgreSQL deployed in the Fako cluster. It provides a graphical interface for database administration, query execution, and monitoring. This deployment is pre-configured to connect to the PostgreSQL cluster with both read-write and read-only endpoints, making database management accessible through a web browser.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Web-Based Interface&lt;/strong>: Full-featured PostgreSQL management from browser&lt;/li>
&lt;li>&lt;strong>Pre-Configured Servers&lt;/strong>: Automatic connection to cluster databases&lt;/li>
&lt;li>&lt;strong>Query Tool&lt;/strong>: Advanced SQL editor with syntax highlighting&lt;/li>
&lt;li>&lt;strong>Visual Database Designer&lt;/strong>: ERD and schema visualization&lt;/li>
&lt;li>&lt;strong>Backup/Restore&lt;/strong>: GUI for database backup operations&lt;/li>
&lt;li>&lt;strong>Server Monitoring&lt;/strong>: Real-time database statistics&lt;/li>
&lt;li>&lt;strong>User Management&lt;/strong>: Graphical user and role administration&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 80&lt;/li>
&lt;li>&lt;strong>Ingress&lt;/strong>: HTTPS access (when configured)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for pgAdmin data&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Server configuration and connection settings&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: Database passwords from AWS Secrets Manager&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 256Mi (request), 512Mi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 250m (request), 500m (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for pgAdmin data and sessions&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>PGADMIN_DEFAULT_EMAIL&lt;/code>&lt;/td>
&lt;td>&lt;code>85landry@gmail.com&lt;/code>&lt;/td>
&lt;td>Admin login email&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>PGADMIN_CONFIG_SERVER_MODE&lt;/code>&lt;/td>
&lt;td>&lt;code>False&lt;/code>&lt;/td>
&lt;td>Desktop mode (single user)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED&lt;/code>&lt;/td>
&lt;td>&lt;code>False&lt;/code>&lt;/td>
&lt;td>No master password needed&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>PGADMIN_SERVER_JSON_FILE&lt;/code>&lt;/td>
&lt;td>&lt;code>/pgadmin4/servers.json&lt;/code>&lt;/td>
&lt;td>Pre-configured servers&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="pre-configured-database-servers">Pre-Configured Database Servers&lt;/h3>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>PostgreSQL Cluster (Read-Write)&lt;/strong>&lt;/p></description></item><item><title>Piper - Local Text-to-Speech Service</title><link>https://blog.landryzetam.net/pages/services/piper/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/piper/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Piper is a fast, local text-to-speech (TTS) service deployed in the Fako cluster. It converts text into natural-sounding speech using neural voice models and exposes its functionality via the Wyoming protocol, making it compatible with voice assistant platforms like Home Assistant.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>CPU-Optimized&lt;/strong>: Runs efficiently on CPU without requiring GPU&lt;/li>
&lt;li>&lt;strong>Wyoming Protocol&lt;/strong>: Compatible with Home Assistant and other voice platforms&lt;/li>
&lt;li>&lt;strong>Multiple Voice Support&lt;/strong>: Various voice models with different qualities&lt;/li>
&lt;li>&lt;strong>Voice Management&lt;/strong>: Automatic voice model management via sidecar container&lt;/li>
&lt;li>&lt;strong>Persistent Storage&lt;/strong>: Voice models cached to avoid re-downloading&lt;/li>
&lt;li>&lt;strong>Scalable&lt;/strong>: Supports multiple concurrent TTS processes&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica deployment with node affinity rules&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 10200 (Wyoming protocol)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for voice model storage&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Configuration for default voice settings&lt;/li>
&lt;li>&lt;strong>Sidecar Container&lt;/strong>: Voice manager for monitoring voice models&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>GPU&lt;/strong>: Not required (CPU-only)&lt;/li>
&lt;li>&lt;strong>Memory&lt;/strong>: 4Gi (request), 8Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 2 cores (request), 4 cores (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for voice model storage&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="environment-settings">Environment Settings&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Default&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>DEFAULT_VOICE&lt;/code>&lt;/td>
&lt;td>&lt;code>en_US-amy-medium&lt;/code>&lt;/td>
&lt;td>Default voice model to use&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>--max-piper-procs&lt;/code>&lt;/td>
&lt;td>&lt;code>8&lt;/code>&lt;/td>
&lt;td>Maximum concurrent TTS processes&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>--data-dir&lt;/code>&lt;/td>
&lt;td>&lt;code>/data&lt;/code>&lt;/td>
&lt;td>Directory for voice data&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>--download-dir&lt;/code>&lt;/td>
&lt;td>&lt;code>/data&lt;/code>&lt;/td>
&lt;td>Directory for downloading voices&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="available-voice-models">Available Voice Models&lt;/h3>
&lt;p>Piper supports various voice models with different qualities:&lt;/p></description></item><item><title>PostgreSQL Cluster Service</title><link>https://blog.landryzetam.net/pages/services/postgres-cluster/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/postgres-cluster/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>The PostgreSQL Cluster is a highly available database service deployed using CloudNative PG (CNPG) operator. It provides a 3-node PostgreSQL 16.2 cluster with automatic failover, backup scheduling, and secure credential management through AWS Secrets Manager. This cluster serves as the primary database backend for multiple services including Keycloak, N8N, and other applications.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>High Availability&lt;/strong>: 3-node cluster with automatic failover&lt;/li>
&lt;li>&lt;strong>Automated Backups&lt;/strong>: Daily scheduled backups at 2 AM&lt;/li>
&lt;li>&lt;strong>Secure Credentials&lt;/strong>: Integration with AWS Secrets Manager&lt;/li>
&lt;li>&lt;strong>Connection Pooling&lt;/strong>: PgBouncer pooler for efficient connections&lt;/li>
&lt;li>&lt;strong>Performance Tuned&lt;/strong>: Optimized PostgreSQL parameters&lt;/li>
&lt;li>&lt;strong>Pod Anti-Affinity&lt;/strong>: Instances spread across different nodes&lt;/li>
&lt;li>&lt;strong>Monitoring Ready&lt;/strong>: Prometheus metrics support&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Cluster&lt;/strong>: 3 PostgreSQL instances (1 primary, 2 replicas)&lt;/li>
&lt;li>&lt;strong>Operator&lt;/strong>: CloudNative PG operator manages the cluster&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: 50Gi persistent volume per instance&lt;/li>
&lt;li>&lt;strong>Pooler&lt;/strong>: PgBouncer connection pooler&lt;/li>
&lt;li>&lt;strong>Backup&lt;/strong>: Scheduled backup with retention policy&lt;/li>
&lt;li>&lt;strong>External Secrets&lt;/strong>: AWS Secrets Manager integration&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Memory&lt;/strong>: 2Gi (request), 4Gi (limit) per instance&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 1 core (request), 2 cores (limit) per instance&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: 50Gi per instance (150Gi total)&lt;/li>
&lt;li>&lt;strong>Storage Class&lt;/strong>: &lt;code>nfs-postgres-v2&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="postgresql-parameters">PostgreSQL Parameters&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Value&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>max_connections&lt;/code>&lt;/td>
&lt;td>&lt;code>200&lt;/code>&lt;/td>
&lt;td>Maximum concurrent connections&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>shared_buffers&lt;/code>&lt;/td>
&lt;td>&lt;code>512MB&lt;/code>&lt;/td>
&lt;td>Memory for caching data&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>effective_cache_size&lt;/code>&lt;/td>
&lt;td>&lt;code>3GB&lt;/code>&lt;/td>
&lt;td>Planner&amp;rsquo;s assumption about cache&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>work_mem&lt;/code>&lt;/td>
&lt;td>&lt;code>8MB&lt;/code>&lt;/td>
&lt;td>Memory for query operations&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>wal_buffers&lt;/code>&lt;/td>
&lt;td>&lt;code>16MB&lt;/code>&lt;/td>
&lt;td>WAL write buffer size&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>maintenance_work_mem&lt;/code>&lt;/td>
&lt;td>&lt;code>64MB&lt;/code>&lt;/td>
&lt;td>Memory for maintenance operations&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>max_wal_size&lt;/code>&lt;/td>
&lt;td>&lt;code>1GB&lt;/code>&lt;/td>
&lt;td>Maximum WAL size before checkpoint&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>checkpoint_timeout&lt;/code>&lt;/td>
&lt;td>&lt;code>5min&lt;/code>&lt;/td>
&lt;td>Time between checkpoints&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="network-access">Network Access&lt;/h3>
&lt;p>The cluster allows connections from:&lt;/p></description></item><item><title>Search</title><link>https://blog.landryzetam.net/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/search/</guid><description/></item><item><title>wger - Self-Hosted Fitness and Workout Manager</title><link>https://blog.landryzetam.net/pages/services/wger/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/wger/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>wger (Workout Manager) is a free, open-source fitness and workout tracking application deployed in the Fako cluster. It provides comprehensive features for managing workouts, tracking nutrition, monitoring body weight, and creating exercise routines. The application includes a large exercise database with images and videos, making it an excellent self-hosted alternative to commercial fitness apps. It&amp;rsquo;s accessible via the web interface and offers both registered user accounts and guest access.&lt;/p></description></item><item><title>Whisper - Speech-to-Text Service</title><link>https://blog.landryzetam.net/pages/services/whisper/readme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.landryzetam.net/pages/services/whisper/readme/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Whisper is an automatic speech recognition (ASR) service deployed in the Fako cluster. It uses OpenAI&amp;rsquo;s Whisper model running on GPU acceleration to provide high-quality speech-to-text transcription. The service is exposed via the Wyoming protocol, making it compatible with various voice assistant platforms.&lt;/p>
&lt;h2 id="key-features">Key Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>GPU Acceleration&lt;/strong>: Runs on NVIDIA GPU for fast transcription&lt;/li>
&lt;li>&lt;strong>Wyoming Protocol&lt;/strong>: Compatible with Home Assistant and other voice platforms&lt;/li>
&lt;li>&lt;strong>Multiple Model Sizes&lt;/strong>: Configurable model size (base, small, medium, large)&lt;/li>
&lt;li>&lt;strong>Voice Activity Detection&lt;/strong>: Built-in VAD for efficient processing&lt;/li>
&lt;li>&lt;strong>Persistent Model Storage&lt;/strong>: Models are cached to avoid re-downloading&lt;/li>
&lt;/ul>
&lt;h2 id="architecture">Architecture&lt;/h2>
&lt;h3 id="components">Components&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Deployment&lt;/strong>: Single-replica GPU deployment pinned to the &lt;code>yeezyai&lt;/code> node&lt;/li>
&lt;li>&lt;strong>Service&lt;/strong>: ClusterIP service on port 10300 (Wyoming protocol)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: PersistentVolumeClaim for model caching&lt;/li>
&lt;li>&lt;strong>ConfigMap&lt;/strong>: Environment configuration for model parameters&lt;/li>
&lt;/ol>
&lt;h3 id="resource-requirements">Resource Requirements&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>GPU&lt;/strong>: 1 NVIDIA GPU (required)&lt;/li>
&lt;li>&lt;strong>Memory&lt;/strong>: 2Gi (request), 4Gi (limit)&lt;/li>
&lt;li>&lt;strong>CPU&lt;/strong>: 2 cores (request), 4 cores (limit)&lt;/li>
&lt;li>&lt;strong>Storage&lt;/strong>: Persistent volume for model storage&lt;/li>
&lt;/ul>
&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="model-parameters-via-configmap">Model Parameters (via ConfigMap)&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Default&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>MODEL&lt;/code>&lt;/td>
&lt;td>&lt;code>base&lt;/code>&lt;/td>
&lt;td>Whisper model size (tiny, base, small, medium, large)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>LANGUAGE&lt;/code>&lt;/td>
&lt;td>&lt;code>en&lt;/code>&lt;/td>
&lt;td>Primary language for transcription&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>COMPUTE_TYPE&lt;/code>&lt;/td>
&lt;td>&lt;code>float16&lt;/code>&lt;/td>
&lt;td>GPU compute precision&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>BEAM_SIZE&lt;/code>&lt;/td>
&lt;td>&lt;code>5&lt;/code>&lt;/td>
&lt;td>Beam search width for decoding&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="voice-activity-detection">Voice Activity Detection&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Parameter&lt;/th>
&lt;th>Default&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>VAD_THRESHOLD&lt;/code>&lt;/td>
&lt;td>&lt;code>0.5&lt;/code>&lt;/td>
&lt;td>Voice activity detection threshold&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>MIN_SPEECH_DURATION_MS&lt;/code>&lt;/td>
&lt;td>&lt;code>250&lt;/code>&lt;/td>
&lt;td>Minimum speech duration in milliseconds&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>MAX_SPEECH_DURATION_S&lt;/code>&lt;/td>
&lt;td>&lt;code>30&lt;/code>&lt;/td>
&lt;td>Maximum speech duration in seconds&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>SPEECH_PAD_MS&lt;/code>&lt;/td>
&lt;td>&lt;code>400&lt;/code>&lt;/td>
&lt;td>Padding around detected speech&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="accessing-the-service">Accessing the Service&lt;/h3>
&lt;p>The Whisper service is available within the cluster at:&lt;/p></description></item></channel></rss>