<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Part6 on Joey's Site</title><link>https://www.joeyaxtell.com/tags/part6/</link><description>Recent content in Part6 on Joey's Site</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 10 Aug 2026 09:00:00 -0600</lastBuildDate><atom:link href="https://www.joeyaxtell.com/tags/part6/index.xml" rel="self" type="application/rss+xml"/><item><title>Running Workloads: From Compose Files to Kubernetes Manifests</title><link>https://www.joeyaxtell.com/p/running-workloads-from-compose-files-to-kubernetes-manifests/</link><pubDate>Mon, 10 Aug 2026 09:00:00 -0600</pubDate><guid>https://www.joeyaxtell.com/p/running-workloads-from-compose-files-to-kubernetes-manifests/</guid><description>&lt;p&gt;&lt;strong&gt;Homelab Kubernetes Series:&lt;/strong&gt; &lt;a class="link" href="https://www.joeyaxtell.com/p/homelab-kubernetes-adventure/" &gt;1. Intro&lt;/a&gt; · &lt;a class="link" href="https://www.joeyaxtell.com/p/installing-kubernetes-picking-microk8s-for-the-homelab/" &gt;2. Installation&lt;/a&gt; · &lt;a class="link" href="https://www.joeyaxtell.com/p/configuring-the-cluster-tls-secrets-and-learning-to-not-lose-a-node/" &gt;3. Configuration&lt;/a&gt; · &lt;a class="link" href="https://www.joeyaxtell.com/p/kubernetes-networking-in-the-homelab-traefik-metallb-and-pi-hole/" &gt;4. Networking&lt;/a&gt; · &lt;a class="link" href="https://www.joeyaxtell.com/p/storage-in-the-homelab-nfs-for-bulk-longhorn-for-anything-with-a-database/" &gt;5. Storage&lt;/a&gt; · &lt;strong&gt;6. Workloads&lt;/strong&gt; · &lt;a class="link" href="https://www.joeyaxtell.com/p/moving-to-argocd-an-app-of-apps-and-the-bug-that-taught-me-how-helm-rendering-works/" &gt;7. ArgoCD&lt;/a&gt; · &lt;a class="link" href="https://www.joeyaxtell.com/p/gitops-in-practice-whats-actually-automated-and-whats-still-manual/" &gt;8. GitOps&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="recap"&gt;Recap
&lt;/h2&gt;&lt;p&gt;Certificates, secrets, networking, and storage are all in place after the last four posts. This one is about the actual workloads: turning what used to be Docker Compose stacks into real Kubernetes manifests, and the conventions that came out of doing that a dozen times over.&lt;/p&gt;
&lt;h2 id="the-structural-pattern"&gt;The structural pattern
&lt;/h2&gt;&lt;p&gt;Nothing fancy here: one folder per application, and inside it a single manifest file with a Deployment, Service, and Ingress concatenated together with &lt;code&gt;---&lt;/code&gt;. No Helm charts for my own apps, no Kustomize overlays, just plain YAML applied with &lt;code&gt;kubectl apply -f&lt;/code&gt;. It&amp;rsquo;s not the most sophisticated pattern, but it maps almost one-to-one onto how I used to think about a Compose service, which made the conversion a lot less intimidating than I expected going in.&lt;/p&gt;
&lt;p&gt;A few conventions repeat across nearly every workload I run, mostly inherited straight from the &lt;a class="link" href="https://www.linuxserver.io/" target="_blank" rel="noopener"
&gt;linuxserver.io&lt;/a&gt; image conventions I was already used to from Compose:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PUID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;PGID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TZ&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;America/Chicago&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Consistent UID/GID across every app made the NFS permissions story from the &lt;a class="link" href="https://www.joeyaxtell.com/p/storage-in-the-homelab-nfs-for-bulk-longhorn-for-anything-with-a-database/" &gt;storage post&lt;/a&gt; a lot simpler: one user, one group, every app writing to shared volumes without stepping on each other&amp;rsquo;s file ownership.&lt;/p&gt;
&lt;h2 id="whats-actually-running"&gt;What&amp;rsquo;s actually running
&lt;/h2&gt;&lt;p&gt;I keep a handful of apps in a dedicated media namespace that I&amp;rsquo;m not going to detail here. What they do and how they&amp;rsquo;re wired up isn&amp;rsquo;t the interesting part of this series. What is relevant to a Kubernetes post: those workloads split across both storage tiers exactly like the last post described (small per-app config volumes on Longhorn, a large shared library on NFS), and one of them needs privileged networking capabilities beyond what the rest of the cluster requires — a reminder that Kubernetes can still handle non-standard networking when you actually need it.&lt;/p&gt;
&lt;p&gt;Outside of that namespace, a few things are worth naming specifically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pi-hole&lt;/strong&gt; — DNS for the network, covered in the &lt;a class="link" href="https://www.joeyaxtell.com/p/kubernetes-networking-in-the-homelab-traefik-metallb-and-pi-hole/" &gt;networking post&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Home Assistant&lt;/strong&gt; — my home automation platform, with its own Ingress and a persistent NFS-backed config volume.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Heimdall&lt;/strong&gt; — a simple landing page/dashboard linking out to everything else I run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diun&lt;/strong&gt; — the update-tracking watcher from the &lt;a class="link" href="https://www.joeyaxtell.com/p/configuring-the-cluster-tls-secrets-and-learning-to-not-lose-a-node/" &gt;configuration post&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-didnt-survive"&gt;What didn&amp;rsquo;t survive
&lt;/h2&gt;&lt;p&gt;Not every experiment stuck around, and that&amp;rsquo;s not really a bad thing. A Kubernetes Dashboard deployment went through three rounds of tweaking over about a week and then got deleted — Traefik plus Grafana plus &lt;code&gt;kubectl&lt;/code&gt; covered what I actually needed, and running a second web UI just to look at the cluster stopped earning its keep. A chat-gateway service got built out over several commits — init container, security context, Sealed Secrets for its API tokens, the works — and was pulled a day later once I decided it wasn&amp;rsquo;t worth the maintenance surface for how often I&amp;rsquo;d actually use it. Its PVC is still sitting there, unclaimed, which is its own small lesson about cleaning up after yourself.&lt;/p&gt;
&lt;p&gt;Neither of those is really a failure story. They&amp;rsquo;re closer to &amp;ldquo;built it, used it for a week, decided it wasn&amp;rsquo;t worth carrying forward,&amp;rdquo; which is a normal part of running a homelab. I&amp;rsquo;d rather show that than pretend every manifest I&amp;rsquo;ve ever written is still in service.&lt;/p&gt;
&lt;h2 id="the-maturity-marker"&gt;The maturity marker
&lt;/h2&gt;&lt;p&gt;The clearest sign that this stack has moved from &amp;ldquo;getting it working&amp;rdquo; to &amp;ldquo;operating it&amp;rdquo; is a single commit that touched twelve deployments at once, adding the failure-tolerance settings from the &lt;a class="link" href="https://www.joeyaxtell.com/p/configuring-the-cluster-tls-secrets-and-learning-to-not-lose-a-node/" &gt;configuration post&lt;/a&gt; — shorter node-failure tolerations, paired with &lt;code&gt;strategy: Recreate&lt;/code&gt; everywhere a &lt;code&gt;ReadWriteOnce&lt;/code&gt; volume is involved. You don&amp;rsquo;t make a change like that on day one. You make it after a node actually goes down and you sit there watching five minutes tick by before anything comes back.&lt;/p&gt;
&lt;h2 id="up-next"&gt;Up next
&lt;/h2&gt;&lt;p&gt;Everything so far has been applied by hand — &lt;code&gt;kubectl apply -f&lt;/code&gt;, one file at a time, from whichever terminal I happened to be in. The next post is about why that stopped being good enough, and moving to ArgoCD.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;◀ Previous:&lt;/strong&gt; &lt;a class="link" href="https://www.joeyaxtell.com/p/storage-in-the-homelab-nfs-for-bulk-longhorn-for-anything-with-a-database/" &gt;5. Storage&lt;/a&gt; | &lt;strong&gt;Next ▶:&lt;/strong&gt; &lt;a class="link" href="https://www.joeyaxtell.com/p/moving-to-argocd-an-app-of-apps-and-the-bug-that-taught-me-how-helm-rendering-works/" &gt;7. ArgoCD&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>