<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Posts on telnetlocalhost</title><link>https://telnetlocalhost.net/posts/</link><description>Recent content in Posts on telnetlocalhost</description><generator>Hugo -- 0.120.0</generator><language>en-us</language><lastBuildDate>Thu, 16 Apr 2026 12:27:18 -0600</lastBuildDate><atom:link href="https://telnetlocalhost.net/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Microwave Ovens</title><link>https://telnetlocalhost.net/posts/microwaves/</link><pubDate>Mon, 29 Sep 2025 17:26:37 -0600</pubDate><guid>https://telnetlocalhost.net/posts/microwaves/</guid><description>Microwave Ovens Imagine going to a professional chef and telling them they have to learn how to use a microwave oven. Imagine sending them to microwave oven school to help them be a better chef. Imagine thinking that microwave oven skills are what is holding your restaurant back from greatness.
If only we could prepare food faster we would have more happy customers. If only we could propare our steaks faster in a microwave oven.</description><content:encoded><![CDATA[<h1 id="microwave-ovens">Microwave Ovens</h1>
<p>Imagine going to a professional chef and telling them they have to learn how to use a microwave oven. Imagine sending them to microwave oven school to help them be a better chef. Imagine thinking that microwave oven skills are what is holding your restaurant back from greatness.</p>
<p>If only we could prepare food faster we would have more happy customers. If only we could propare our steaks faster in a microwave oven. Absolutely ridiculous.</p>
<p>Nobody is offering professional microwave oven operating services. And, when someone is paying for professional services but receives microwave oven services it probably feels like paying for food at Applebees-disappointment and sadness. If Costco can make hot dogs without a microwave and sell them for $1 you can write your stupid webapp without AI.</p>
<p>If you are making popcorn at home and you want some microplastics sure, use the microwave oven, I don&rsquo;t care. You might get an <code>rm -rf /</code> but what are you losing? Some dot files you forgot to backup? It&rsquo;s fine.</p>
]]></content:encoded></item><item><title>Analytics with Hugo</title><link>https://telnetlocalhost.net/posts/analytics_with_hugo/</link><pubDate>Tue, 14 Nov 2023 18:00:11 -0700</pubDate><guid>https://telnetlocalhost.net/posts/analytics_with_hugo/</guid><description>A privacy respecting approach
Umami Infrastructure Umami is the tool I&amp;rsquo;m using for collecting and viewing the user analytics. My needs are simple—I just want to know how popular I am.
Some prior infrastructure that is already setup is Kubernetes, Flux, Nginx Ingress, Certificates, and Hugo. I&amp;rsquo;ll get to posts describing the full setup at some time. In my git repo I have the following files for Umami
1 2 3 4 .</description><content:encoded><![CDATA[<p>A privacy respecting approach</p>
<h2 id="umami-infrastructure">Umami Infrastructure</h2>
<p><a href="https://umami.is/docs">Umami</a> is the tool I&rsquo;m using for collecting and viewing the user analytics. My needs are simple—I just want to know how popular I am.</p>
<p>Some prior infrastructure that is already setup is Kubernetes, Flux, Nginx Ingress, Certificates, and <a href="/posts/a_simple_hugo_site/">Hugo</a>. I&rsquo;ll get to posts describing the full setup at some time. In my git repo I have the following files for Umami</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>.
</span></span><span style="display:flex;"><span>├── kustomization.yaml
</span></span><span style="display:flex;"><span>├── umami-secrets.yaml
</span></span><span style="display:flex;"><span>└── umami.yaml
</span></span></code></pre></td></tr></table>
</div>
</div><p>The file <code>kustomization.yaml</code> is simple and is just a reference to the other two. <code>umami-secrets.yaml</code> is an opaque secret encrypted using sops. Unencrypted it has the following contents.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">8
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>apiVersion: v1
</span></span><span style="display:flex;"><span>kind: Secret
</span></span><span style="display:flex;"><span>metadata:
</span></span><span style="display:flex;"><span>    name: umami
</span></span><span style="display:flex;"><span>    namespace: public
</span></span><span style="display:flex;"><span>type: Opaque
</span></span><span style="display:flex;"><span>stringData:
</span></span><span style="display:flex;"><span>    DB_CONNECTION_STRING: postgres://umami:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@postgresql.data.svc.cluster.local:5432/umami?sslmode=disable
</span></span></code></pre></td></tr></table>
</div>
</div><p>Note that I manually created the postgres user and database with values that match the connection string above.</p>
<p><code>umami.yaml</code> has the following contents</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span><span style="color:#f92672">---</span>
</span></span><span style="display:flex;"><span>apiVersion: helm<span style="color:#f92672">.</span>toolkit<span style="color:#f92672">.</span>fluxcd<span style="color:#f92672">.</span>io<span style="color:#f92672">/</span>v2beta1
</span></span><span style="display:flex;"><span>kind: HelmRelease
</span></span><span style="display:flex;"><span>metadata:
</span></span><span style="display:flex;"><span>  name: <span style="color:#f92672">&amp;</span>app umami
</span></span><span style="display:flex;"><span>  namespace: public
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>spec:
</span></span><span style="display:flex;"><span>  interval: <span style="color:#ae81ff">15</span>m
</span></span><span style="display:flex;"><span>  chart:
</span></span><span style="display:flex;"><span>    spec:
</span></span><span style="display:flex;"><span>      chart: umami
</span></span><span style="display:flex;"><span>      version: <span style="color:#ae81ff">1.20</span><span style="color:#f92672">.</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>      interval: <span style="color:#ae81ff">15</span>m
</span></span><span style="display:flex;"><span>      sourceRef:
</span></span><span style="display:flex;"><span>        kind: HelmRepository
</span></span><span style="display:flex;"><span>        name: christianknell
</span></span><span style="display:flex;"><span>        namespace: flux<span style="color:#f92672">-</span>system
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  values:
</span></span><span style="display:flex;"><span>    umami:
</span></span><span style="display:flex;"><span>      removeDisableLoginEnv: true
</span></span><span style="display:flex;"><span>      trackerScriptName: analytics
</span></span><span style="display:flex;"><span>      hostname: <span style="color:#f92672">&amp;</span>host analytics<span style="color:#f92672">.$</span>{SECRET_DOMAIN2}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    database:
</span></span><span style="display:flex;"><span>      existingSecret: <span style="color:#f92672">*</span>app
</span></span><span style="display:flex;"><span>      databaseUrlKey: DB_CONNECTION_STRING
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    postgresql:
</span></span><span style="display:flex;"><span>      enabled: false
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    ingress:
</span></span><span style="display:flex;"><span>      enabled: true
</span></span><span style="display:flex;"><span>      hosts:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-</span> host: <span style="color:#f92672">*</span>host
</span></span><span style="display:flex;"><span>          paths:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">-</span> path: <span style="color:#f92672">/</span>
</span></span><span style="display:flex;"><span>              pathType: Prefix
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      tls:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-</span> secretName: wildcard2<span style="color:#f92672">-</span>cert<span style="color:#f92672">-</span>tls
</span></span><span style="display:flex;"><span>          hosts:
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">-</span> <span style="color:#f92672">*</span>host
</span></span></code></pre></td></tr></table>
</div>
</div><p>Values for <code>trackerScriptName</code> and <code>hostname</code> will need to be changed to dodge ad blockers. Use the data only for good, not evil.</p>
<p>Shoutout to <a href="https://artifacthub.io/packages/helm/christianknell/umami#views">christianknell</a> for the helm chart.</p>
<h2 id="umami-setup">Umami Setup</h2>
<p>Navigate to the URL defined in the above ingress definition. Default username is <em>admin</em> and the default password is <em>umami</em>. Change these ASAP.</p>
<p>Go to the settings and add a website:</p>
<p><img loading="lazy" src="/images/add-website.png" alt="Hugo add website screenshot"  title="Hugo add website screenshot"  />
</p>
<p>Once that is done, click on the code button to get the data you need for the next part.</p>
<h2 id="analytics-in-hugo">Analytics in Hugo</h2>
<p>How to do this will depend on the theme. I&rsquo;m using the PaperMod theme and here&rsquo;s how I did the next part.</p>
<p>First, I created a partial file. Hugo will look in this directory and overwrite the contents of your theme with what is in here. PaperMod has <code>extend_head.html</code> for custom header resources like this.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>layouts
</span></span><span style="display:flex;"><span>└── partials
</span></span><span style="display:flex;"><span>    └── extend_head.html
</span></span></code></pre></td></tr></table>
</div>
</div><p>Contents of <code>extend_head.html</code> are</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>{{ if and .Site.GoogleAnalytics (not .Site.IsServer) }}
</span></span><span style="display:flex;"><span>{{ template &#34;_internal/google_analytics.html&#34; . }}
</span></span><span style="display:flex;"><span>{{ else if and .Site.Params.umami.enabled (not .Site.IsServer) }}
</span></span><span style="display:flex;"><span>&lt;script
</span></span><span style="display:flex;"><span>  async
</span></span><span style="display:flex;"><span>  defer
</span></span><span style="display:flex;"><span>  data-website-id=&#34;{{ .Site.Params.umami.websiteId }}&#34;
</span></span><span style="display:flex;"><span>  src=&#34;{{ .Site.Params.umami.jsLocation }}&#34;
</span></span><span style="display:flex;"><span>&gt;&lt;/script&gt;
</span></span><span style="display:flex;"><span>{{ end }}
</span></span></code></pre></td></tr></table>
</div>
</div><p>The parameters referenced there are defined in Config.toml</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>[params.umami]
</span></span><span style="display:flex;"><span>enabled = true
</span></span><span style="display:flex;"><span>websiteId = &#34;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&#34;
</span></span><span style="display:flex;"><span>jsLocation = &#34;https://analytics.telnetlocalhost.net/analytics.js&#34;
</span></span></code></pre></td></tr></table>
</div>
</div><p>This data comes from the Umami settings for the website. And, now after visiting the website I go back to umami and see it working:</p>
<p><img loading="lazy" src="/images/umami.png" alt="Umami"  title="Umami dashboard screenshot"  />
</p>
<h2 id="conclusion">Conclusion</h2>
<p>Not very popular.</p>
]]></content:encoded></item><item><title>A Simple Hugo Site</title><link>https://telnetlocalhost.net/posts/a_simple_hugo_site/</link><pubDate>Thu, 10 Aug 2023 20:39:48 -0600</pubDate><guid>https://telnetlocalhost.net/posts/a_simple_hugo_site/</guid><description>Or is it
No (of course not) This whole thing runs on kubernetes using the k3s distribution and is managed using Flux for gitops. At some other time I&amp;rsquo;ll go into further details on how that all works. Here I&amp;rsquo;ll just focus on the parts closer into getting Hugo running. Kustomize to provide further templating.
I swear that kubernetes is at the same place in its lifecycle that JavaScript was at 10 years ago.</description><content:encoded><![CDATA[<p>Or is it</p>
<h2 id="no-of-course-not">No (of course not)</h2>
<p>This whole thing runs on kubernetes using the <a href="https://k3s.io/">k3s</a> distribution and is managed using <a href="https://fluxcd.io/">Flux</a> for gitops. At some other time I&rsquo;ll go into further details on how that all works. Here I&rsquo;ll just focus on the parts closer into getting Hugo running. <a href="https://kustomize.io/">Kustomize</a> to provide further templating.</p>
<p>I swear that kubernetes is at the same place in its lifecycle that JavaScript was at 10 years ago. A million different solutions to transpile and bundle your code because the end result is not something anyone wants to touch directly. Anyway&hellip;</p>
<h2 id="step-1-a-webserver">Step 1: A webserver</h2>
<p>The web server being used is <a href="https://github.com/kubernetes/ingress-nginx">Ingress NGINX Controller</a>. Certificates are managed using <a href="https://cert-manager.io/docs/">cert-manager</a>. <a href="https://metallb.universe.tf/">Metallb</a> is being used as a load balancer. There&rsquo;s a lot here that I won&rsquo;t go into detail now but when requests come in on port 80 or 443 they get routed to the address metallb assigned the ingress controller which handles the SSL portion and proxies the request to the hugo service.</p>
<h2 id="step-2-a-hugo">Step 2: A Hugo</h2>
<p>Here&rsquo;s the directory structure of the service definition:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>.
</span></span><span style="display:flex;"><span>├── app
</span></span><span style="display:flex;"><span>│   ├── hugo.env
</span></span><span style="display:flex;"><span>│   ├── hugo.yaml
</span></span><span style="display:flex;"><span>│   └── kustomization.yaml
</span></span><span style="display:flex;"><span>├── ks.yaml
</span></span><span style="display:flex;"><span>└── kustomization.yaml
</span></span></code></pre></td></tr></table>
</div>
</div><p>The top level <code>kustomization.yaml</code> is trivial and just simple resource lists like this</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>apiVersion: kustomize.config.k8s.io/v1beta1
</span></span><span style="display:flex;"><span>kind: Kustomization
</span></span><span style="display:flex;"><span>resources:
</span></span><span style="display:flex;"><span>  - app
</span></span><span style="display:flex;"><span>  - ks.yaml
</span></span></code></pre></td></tr></table>
</div>
</div><p>The <code>ks.yaml</code> is a flux Kustomization</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>apiVersion: kustomize<span style="color:#f92672">.</span>toolkit<span style="color:#f92672">.</span>fluxcd<span style="color:#f92672">.</span>io<span style="color:#f92672">/</span>v1beta2
</span></span><span style="display:flex;"><span>kind: Kustomization
</span></span><span style="display:flex;"><span>metadata:
</span></span><span style="display:flex;"><span>  name: hugo
</span></span><span style="display:flex;"><span>  namespace: flux<span style="color:#f92672">-</span>system
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>spec:
</span></span><span style="display:flex;"><span>  path: <span style="color:#e6db74">&#39;./cluster/andor/apps/public/hugo/app/&#39;</span>
</span></span><span style="display:flex;"><span>  interval: <span style="color:#ae81ff">1</span>m0s
</span></span><span style="display:flex;"><span>  prune: true
</span></span><span style="display:flex;"><span>  sourceRef:
</span></span><span style="display:flex;"><span>    kind: GitRepository
</span></span><span style="display:flex;"><span>    name: flux<span style="color:#f92672">-</span>system
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  decryption:
</span></span><span style="display:flex;"><span>    provider: sops
</span></span><span style="display:flex;"><span>    secretRef:
</span></span><span style="display:flex;"><span>      name: sops<span style="color:#f92672">-</span>gpg
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  postBuild:
</span></span><span style="display:flex;"><span>    substituteFrom:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> kind: ConfigMap
</span></span><span style="display:flex;"><span>        name: global<span style="color:#f92672">-</span>vars
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> kind: ConfigMap
</span></span><span style="display:flex;"><span>        name: hugo<span style="color:#f92672">-</span>site<span style="color:#f92672">-</span>version
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> kind: Secret
</span></span><span style="display:flex;"><span>        name: global<span style="color:#f92672">-</span>secrets
</span></span></code></pre></td></tr></table>
</div>
</div><p>This ensures I can use variables in the definition of hugo.</p>
<p>The other <code>kustomization.yaml</code> file is a little more interesting. This one creates a config map for me</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>apiVersion: kustomize.config.k8s.io/v1beta1
</span></span><span style="display:flex;"><span>kind: Kustomization
</span></span><span style="display:flex;"><span>resources:
</span></span><span style="display:flex;"><span>  - hugo.yaml
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>generatorOptions:
</span></span><span style="display:flex;"><span>  disableNameSuffixHash: true
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>configMapGenerator:
</span></span><span style="display:flex;"><span>- name: hugo-site-version
</span></span><span style="display:flex;"><span>  namespace: flux-system
</span></span><span style="display:flex;"><span>  envs:
</span></span><span style="display:flex;"><span>  - hugo.env
</span></span></code></pre></td></tr></table>
</div>
</div><p>This reads <code>hugo.env</code></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>HUGO_VERSION=e8dd92a014a9c7be9a4f0132241d1644953a7805
</span></span></code></pre></td></tr></table>
</div>
</div><p>And creates a config map like this:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">❯</span> kubectl <span style="color:#f92672">-</span>n flux<span style="color:#f92672">-</span>system get configmaps hugo<span style="color:#f92672">-</span>site<span style="color:#f92672">-</span>version <span style="color:#f92672">-</span>o yaml
</span></span><span style="display:flex;"><span>apiVersion: v1
</span></span><span style="display:flex;"><span>data:
</span></span><span style="display:flex;"><span>  HUGO_VERSION: e8dd92a014a9c7be9a4f0132241d1644953a7805
</span></span><span style="display:flex;"><span>kind: ConfigMap
</span></span><span style="display:flex;"><span>metadata:
</span></span><span style="display:flex;"><span>  creationTimestamp: <span style="color:#e6db74">&#34;2023-08-10T23:57:47Z&#34;</span>
</span></span><span style="display:flex;"><span>  labels:
</span></span><span style="display:flex;"><span>    kustomize<span style="color:#f92672">.</span>toolkit<span style="color:#f92672">.</span>fluxcd<span style="color:#f92672">.</span>io<span style="color:#f92672">/</span>name: hugo
</span></span><span style="display:flex;"><span>    kustomize<span style="color:#f92672">.</span>toolkit<span style="color:#f92672">.</span>fluxcd<span style="color:#f92672">.</span>io<span style="color:#f92672">/</span>namespace: flux<span style="color:#f92672">-</span>system
</span></span><span style="display:flex;"><span>  name: hugo<span style="color:#f92672">-</span>site<span style="color:#f92672">-</span>version
</span></span><span style="display:flex;"><span>  namespace: flux<span style="color:#f92672">-</span>system
</span></span><span style="display:flex;"><span>  resourceVersion: <span style="color:#e6db74">&#34;34262521&#34;</span>
</span></span><span style="display:flex;"><span>  uid: <span style="color:#ae81ff">7791</span>cb6e<span style="color:#f92672">-</span>ccf9<span style="color:#f92672">-</span><span style="color:#ae81ff">4550</span><span style="color:#f92672">-</span>bc1c<span style="color:#f92672">-</span><span style="color:#ae81ff">658</span>a031e28e3
</span></span></code></pre></td></tr></table>
</div>
</div><p>The wonderful helm chart by <a href="https://github.com/bjw-s/helm-charts/tree/main/charts/library/common">bjw-s</a> is used for creating a helm release of a docker image.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">55
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">56
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">57
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">58
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">59
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">60
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">61
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">62
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">63
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">64
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">65
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">66
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">67
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">68
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">69
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span><span style="color:#f92672">---</span>
</span></span><span style="display:flex;"><span>apiVersion: helm<span style="color:#f92672">.</span>toolkit<span style="color:#f92672">.</span>fluxcd<span style="color:#f92672">.</span>io<span style="color:#f92672">/</span>v2beta1
</span></span><span style="display:flex;"><span>kind: HelmRelease
</span></span><span style="display:flex;"><span>metadata:
</span></span><span style="display:flex;"><span>  name: hugo
</span></span><span style="display:flex;"><span>  namespace: public
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>spec:
</span></span><span style="display:flex;"><span>  chart:
</span></span><span style="display:flex;"><span>    spec:
</span></span><span style="display:flex;"><span>      chart: app<span style="color:#f92672">-</span>template
</span></span><span style="display:flex;"><span>      version: <span style="color:#ae81ff">1.5</span><span style="color:#f92672">.</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>      reconcileStrategy: ChartVersion
</span></span><span style="display:flex;"><span>      sourceRef:
</span></span><span style="display:flex;"><span>        kind: HelmRepository
</span></span><span style="display:flex;"><span>        name: bjw<span style="color:#f92672">-</span>s
</span></span><span style="display:flex;"><span>        namespace: flux<span style="color:#f92672">-</span>system
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  interval: <span style="color:#ae81ff">5</span>m0s
</span></span><span style="display:flex;"><span>  install:
</span></span><span style="display:flex;"><span>    createNamespace: true
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  values:
</span></span><span style="display:flex;"><span>    image:
</span></span><span style="display:flex;"><span>      repository: code<span style="color:#f92672">.</span>example<span style="color:#f92672">.</span>com<span style="color:#f92672">/</span>org<span style="color:#f92672">/</span>hugosite
</span></span><span style="display:flex;"><span>      tag: <span style="color:#f92672">$</span>{HUGO_VERSION}
</span></span><span style="display:flex;"><span>      pullPolicy: IfNotPresent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    controller:
</span></span><span style="display:flex;"><span>      strategy: RollingUpdate
</span></span><span style="display:flex;"><span>      replicas: <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    service:
</span></span><span style="display:flex;"><span>      main:
</span></span><span style="display:flex;"><span>        type: LoadBalancer
</span></span><span style="display:flex;"><span>        ports:
</span></span><span style="display:flex;"><span>          http:
</span></span><span style="display:flex;"><span>            enabled: true
</span></span><span style="display:flex;"><span>            port: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>            targetPort: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>            protocol: TCP
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    ingress:
</span></span><span style="display:flex;"><span>      main:
</span></span><span style="display:flex;"><span>        enabled: true
</span></span><span style="display:flex;"><span>        ingressClassName: <span style="color:#e6db74">&#34;nginx&#34;</span>
</span></span><span style="display:flex;"><span>        annotations:
</span></span><span style="display:flex;"><span>          hajimari<span style="color:#f92672">.</span>io<span style="color:#f92672">/</span>icon: simple<span style="color:#f92672">-</span>icons:hugo
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        hosts:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">-</span> host: <span style="color:#f92672">&amp;</span>host <span style="color:#e6db74">&#34;hugo.${SECRET_DOMAIN2}&#34;</span>
</span></span><span style="display:flex;"><span>            paths:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">-</span> path: <span style="color:#f92672">/</span>
</span></span><span style="display:flex;"><span>                pathType: Prefix
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        tls:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">-</span> secretName: wildcard2<span style="color:#f92672">-</span>cert<span style="color:#f92672">-</span>tls
</span></span><span style="display:flex;"><span>            hosts:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">-</span> <span style="color:#f92672">*</span>host
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    resources:
</span></span><span style="display:flex;"><span>      requests:
</span></span><span style="display:flex;"><span>        cpu: <span style="color:#ae81ff">20</span>m
</span></span><span style="display:flex;"><span>        memory: <span style="color:#ae81ff">125</span>M
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      limits:
</span></span><span style="display:flex;"><span>        cpu: <span style="color:#ae81ff">50</span>m
</span></span><span style="display:flex;"><span>        memory: <span style="color:#ae81ff">256</span>M
</span></span></code></pre></td></tr></table>
</div>
</div><p>The image tag is defined as <code>${HUGO_VERSION}</code>. This value comes from hugo.env. And given that this is a Rube Goldberg machine no way am I setting this by hand.</p>
<h2 id="step-3-the-cd-continuous-delivery">Step 3: The CD (continuous delivery)</h2>
<p>Continuous delivery for Hugo is managed using a self-hosted gitea instance. That&rsquo;s a separate topic and I&rsquo;m not sold on my own hosted solution for this because of bootstrap problems. But, for Hugo I think it isn&rsquo;t too egregious. It has a great package registry. The action runner isn&rsquo;t designed for kubernetes and has some rough edges. But I have it working.</p>
<p>Here&rsquo;s the Dockerfile for hugo that I&rsquo;m using.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>FROM alpine:<span style="color:#ae81ff">3.9</span> AS build
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># The Hugo version</span>
</span></span><span style="display:flex;"><span>ARG VERSION<span style="color:#f92672">=</span><span style="color:#ae81ff">0.113</span><span style="color:#f92672">.</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>ADD https:<span style="color:#f92672">//</span>github<span style="color:#f92672">.</span>com<span style="color:#f92672">/</span>gohugoio<span style="color:#f92672">/</span>hugo<span style="color:#f92672">/</span>releases<span style="color:#f92672">/</span>download<span style="color:#f92672">/</span>v<span style="color:#f92672">$</span>{VERSION}<span style="color:#f92672">/</span>hugo_<span style="color:#f92672">$</span>{VERSION}_Linux<span style="color:#f92672">-</span><span style="color:#ae81ff">64</span>bit<span style="color:#f92672">.</span>tar<span style="color:#f92672">.</span>gz <span style="color:#f92672">/</span>hugo<span style="color:#f92672">.</span>tar<span style="color:#f92672">.</span>gz
</span></span><span style="display:flex;"><span>RUN tar <span style="color:#f92672">-</span>zxvf hugo<span style="color:#f92672">.</span>tar<span style="color:#f92672">.</span>gz
</span></span><span style="display:flex;"><span>RUN <span style="color:#f92672">/</span>hugo version
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># We add git to the build stage, because Hugo needs it with --enableGitInfo</span>
</span></span><span style="display:flex;"><span>RUN apk add <span style="color:#f92672">--</span>no<span style="color:#f92672">-</span>cache git
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># The source files are copied to /site</span>
</span></span><span style="display:flex;"><span>COPY <span style="color:#f92672">.</span> <span style="color:#f92672">/</span>site
</span></span><span style="display:flex;"><span>WORKDIR <span style="color:#f92672">/</span>site
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># And then we just run Hugo</span>
</span></span><span style="display:flex;"><span>RUN <span style="color:#f92672">/</span>hugo <span style="color:#f92672">--</span>minify <span style="color:#f92672">--</span>enableGitInfo
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># stage 2</span>
</span></span><span style="display:flex;"><span>FROM nginx:<span style="color:#ae81ff">1.15</span><span style="color:#f92672">-</span>alpine
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>WORKDIR <span style="color:#f92672">/</span>usr<span style="color:#f92672">/</span>share<span style="color:#f92672">/</span>nginx<span style="color:#f92672">/</span>html<span style="color:#f92672">/</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Clean the default public folder</span>
</span></span><span style="display:flex;"><span>RUN rm <span style="color:#f92672">-</span>fr <span style="color:#f92672">*</span> <span style="color:#f92672">.</span><span style="color:#960050;background-color:#1e0010">??</span><span style="color:#f92672">*</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Finally, the &#34;public&#34; folder generated by Hugo in the previous stage</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># is copied into the public fold of nginx</span>
</span></span><span style="display:flex;"><span>COPY <span style="color:#f92672">--</span>from<span style="color:#f92672">=</span>build <span style="color:#f92672">/</span>site<span style="color:#f92672">/</span>public <span style="color:#f92672">/</span>usr<span style="color:#f92672">/</span>share<span style="color:#f92672">/</span>nginx<span style="color:#f92672">/</span>html
</span></span><span style="display:flex;"><span>RUN chown <span style="color:#f92672">-</span>R <span style="color:#ae81ff">100</span>:<span style="color:#ae81ff">101</span> <span style="color:#f92672">/</span>usr<span style="color:#f92672">/</span>share<span style="color:#f92672">/</span>nginx<span style="color:#f92672">/</span>html
</span></span></code></pre></td></tr></table>
</div>
</div><p>At this time this container image is 7.7 MiB. That&rsquo;s a nice lean container. &#x1f604;</p>
<p>Here&rsquo;s the workflow file in the hugo repository:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">55
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">56
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">57
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">58
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">59
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">60
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">61
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">62
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>name: Build <span style="color:#f92672">and</span> push image
</span></span><span style="display:flex;"><span>on:
</span></span><span style="display:flex;"><span>  push:
</span></span><span style="display:flex;"><span>    branches: [main]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>jobs:
</span></span><span style="display:flex;"><span>  deploy:
</span></span><span style="display:flex;"><span>    runs<span style="color:#f92672">-</span>on: ubuntu<span style="color:#f92672">-</span>latest
</span></span><span style="display:flex;"><span>    volumes:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> <span style="color:#f92672">/</span><span style="color:#66d9ef">var</span><span style="color:#f92672">/</span>run<span style="color:#f92672">/</span>docker<span style="color:#f92672">.</span>sock:<span style="color:#f92672">/</span><span style="color:#66d9ef">var</span><span style="color:#f92672">/</span>run<span style="color:#f92672">/</span>docker<span style="color:#f92672">.</span>sock
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    container:
</span></span><span style="display:flex;"><span>      image: catthehacker<span style="color:#f92672">/</span>ubuntu:act<span style="color:#f92672">-</span>latest
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    steps:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> name: Checkout repo
</span></span><span style="display:flex;"><span>        uses: actions<span style="color:#f92672">/</span>checkout<span style="color:#960050;background-color:#1e0010">@</span>v3
</span></span><span style="display:flex;"><span>        with:
</span></span><span style="display:flex;"><span>          submodules: recursive
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> name: Log <span style="color:#f92672">in</span> to the <span style="color:#a6e22e">Container</span> registry
</span></span><span style="display:flex;"><span>        uses: docker<span style="color:#f92672">/</span>login<span style="color:#f92672">-</span>action<span style="color:#960050;background-color:#1e0010">@</span>v2
</span></span><span style="display:flex;"><span>        with:
</span></span><span style="display:flex;"><span>          registry: code<span style="color:#f92672">.</span>example<span style="color:#f92672">.</span>com
</span></span><span style="display:flex;"><span>          username: name
</span></span><span style="display:flex;"><span>          password: <span style="color:#f92672">$</span>{{ secrets<span style="color:#f92672">.</span>REGISTRY_TOKEN }}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> name: Docker build <span style="color:#f92672">and</span> push
</span></span><span style="display:flex;"><span>        run: <span style="color:#f92672">|</span>
</span></span><span style="display:flex;"><span>          docker build <span style="color:#f92672">--</span>build<span style="color:#f92672">-</span>arg GIT_COMMIT<span style="color:#f92672">=$</span>(git rev<span style="color:#f92672">-</span>parse HEAD) <span style="color:#f92672">-</span>t org<span style="color:#f92672">/</span>hugosite:<span style="color:#f92672">$</span>(git rev<span style="color:#f92672">-</span>parse HEAD) <span style="color:#f92672">--</span>progress<span style="color:#f92672">=</span>plain <span style="color:#f92672">.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          docker tag org<span style="color:#f92672">/</span>hugosite:<span style="color:#f92672">$</span>(git rev<span style="color:#f92672">-</span>parse HEAD) code<span style="color:#f92672">.</span>example<span style="color:#f92672">.</span>com<span style="color:#f92672">/</span>org<span style="color:#f92672">/</span>hugosite:<span style="color:#f92672">$</span>(git rev<span style="color:#f92672">-</span>parse HEAD)
</span></span><span style="display:flex;"><span>          docker image push code<span style="color:#f92672">.</span>example<span style="color:#f92672">.</span>com<span style="color:#f92672">/</span>org<span style="color:#f92672">/</span>hugosite:<span style="color:#f92672">$</span>(git rev<span style="color:#f92672">-</span>parse HEAD)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          docker tag org<span style="color:#f92672">/</span>hugosite:<span style="color:#f92672">$</span>(git rev<span style="color:#f92672">-</span>parse HEAD) code<span style="color:#f92672">.</span>example<span style="color:#f92672">.</span>com<span style="color:#f92672">/</span>org<span style="color:#f92672">/</span>hugosite:latest
</span></span><span style="display:flex;"><span>          docker image push code<span style="color:#f92672">.</span>example<span style="color:#f92672">.</span>com<span style="color:#f92672">/</span>org<span style="color:#f92672">/</span>hugosite:latest
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> name: Checkout homelab
</span></span><span style="display:flex;"><span>        run: <span style="color:#f92672">|</span>
</span></span><span style="display:flex;"><span>          mkdir <span style="color:#f92672">-</span>p <span style="color:#f92672">~/.</span>ssh
</span></span><span style="display:flex;"><span>          echo <span style="color:#e6db74">&#34;${{ secrets.ID_RSA }}&#34;</span> <span style="color:#f92672">&gt;</span> <span style="color:#f92672">~/.</span>ssh<span style="color:#f92672">/</span>id_rsa
</span></span><span style="display:flex;"><span>          chmod <span style="color:#ae81ff">600</span> <span style="color:#f92672">~/.</span>ssh<span style="color:#f92672">/</span>id_rsa
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          echo <span style="color:#e6db74">&#34;${{ secrets.ID_RSA_PUB }}&#34;</span> <span style="color:#f92672">&gt;</span> <span style="color:#f92672">~/.</span>ssh<span style="color:#f92672">/</span>id_rsa<span style="color:#f92672">.</span>pub
</span></span><span style="display:flex;"><span>          chmod <span style="color:#ae81ff">644</span> <span style="color:#f92672">~/.</span>ssh<span style="color:#f92672">/</span>id_rsa<span style="color:#f92672">.</span>pub
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          echo <span style="color:#e6db74">&#34;${{ secrets.KNOWN_HOSTS }}&#34;</span> <span style="color:#f92672">&gt;</span> <span style="color:#f92672">~/.</span>ssh<span style="color:#f92672">/</span>known_hosts
</span></span><span style="display:flex;"><span>          chmod <span style="color:#ae81ff">644</span> <span style="color:#f92672">~/.</span>ssh<span style="color:#f92672">/</span>known_hosts
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          git clone git<span style="color:#960050;background-color:#1e0010">@</span>gitlab<span style="color:#f92672">.</span>com:name<span style="color:#f92672">/</span>homeserver<span style="color:#f92672">.</span>git
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">-</span> name: Set hugosite version
</span></span><span style="display:flex;"><span>        run: <span style="color:#f92672">|</span>
</span></span><span style="display:flex;"><span>          echo <span style="color:#e6db74">&#34;HUGO_VERSION=$(git rev-parse HEAD)&#34;</span> <span style="color:#f92672">&gt;</span> homeserver<span style="color:#f92672">/</span>cluster<span style="color:#f92672">/</span>andor<span style="color:#f92672">/</span>apps<span style="color:#f92672">/</span>public<span style="color:#f92672">/</span>hugo<span style="color:#f92672">/</span>app<span style="color:#f92672">/</span>hugo<span style="color:#f92672">.</span>env
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          git config <span style="color:#f92672">--</span>global user<span style="color:#f92672">.</span>email <span style="color:#e6db74">&#34;name@example.com&#34;</span>
</span></span><span style="display:flex;"><span>          git config <span style="color:#f92672">--</span>global user<span style="color:#f92672">.</span>name <span style="color:#e6db74">&#34;name (CI bot)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          cd homeserver
</span></span><span style="display:flex;"><span>          git add cluster<span style="color:#f92672">/</span>andor<span style="color:#f92672">/</span>apps<span style="color:#f92672">/</span>public<span style="color:#f92672">/</span>hugo<span style="color:#f92672">/</span>app<span style="color:#f92672">/</span>hugo<span style="color:#f92672">.</span>env
</span></span><span style="display:flex;"><span>          git commit <span style="color:#f92672">-</span>m <span style="color:#e6db74">&#34;Hugo version update from CI&#34;</span>
</span></span><span style="display:flex;"><span>          git push origin main
</span></span></code></pre></td></tr></table>
</div>
</div><p>I&rsquo;ve replaced some references here with generic example and name but you see what&rsquo;s happening.  The docker image is being built and pushed to the private registry. And then the hash of the last git commit is written out to the hugo.env file in the homelab repo (which kustomize turns into a configmap) and that&rsquo;s pushed up which flux will make go live. The pipeline takes 14 seconds to run (which is great) but because of how I have flux setup it can take more than 5 minutes for updates to be reflected live.</p>
<h2 id="is-it-working">Is It Working?</h2>
<p>Yes. Here&rsquo;s a performance chart.</p>
<p><img loading="lazy" src="/images/hugo_performance.png" alt="Grafana request chart"  title="Grafana request chart"  />
</p>
<h2 id="conclusion">Conclusion</h2>
<p>All this for a blog I&rsquo;ll update twice.</p>
]]></content:encoded></item><item><title>Welcome to my new blog</title><link>https://telnetlocalhost.net/posts/my-first-post/</link><pubDate>Tue, 06 Jun 2023 19:09:58 -0600</pubDate><guid>https://telnetlocalhost.net/posts/my-first-post/</guid><description>I&amp;rsquo;m definitely going to update this one.
Hosting information This is all hosted on my old computer sitting in my living room. Currently the power button is my daughter&amp;rsquo;s favourite thing to play with so reliability is not great. The computer is running k3s and the cluster is managed using flux. I expect to spend some time documenting this rube goldberg machine.</description><content:encoded><![CDATA[<p>I&rsquo;m definitely going to update this one.</p>
<h1 id="hosting-information">Hosting information</h1>
<p>This is all hosted on my old computer sitting in my living room. Currently the power button is my daughter&rsquo;s favourite thing to play with so reliability is not great. The computer is running k3s and the cluster is managed using flux. I expect to spend some time documenting this rube goldberg machine.</p>
]]></content:encoded></item></channel></rss>