estradiol.cloud/public/posts/hugo-on-k8s-nginx/index.html

326 lines
19 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script><title>Hugo on Kubernetes &amp; NGINX &ndash; estradiol.cloud</title>
2024-02-29 06:49:15 +00:00
<meta name="description" content="Making vanity projects easy since 2024">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/academicons/1.9.4/css/academicons.min.css" integrity="sha512-IW0nhlW5MgNydsXJO40En2EoCkTTjZhI3yuODrZIc8cQ4h1XcF53PsqDHa09NqnkXuIe0Oiyyj171BqZFwISBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
2024-02-29 06:49:15 +00:00
<link rel="stylesheet" href="http://localhost:1313/css/palettes/material.css">
<link rel="stylesheet" href="http://localhost:1313/css/risotto.css">
<link rel="stylesheet" href="http://localhost:1313/css/custom.css">
</head>
<body>
<div class="page">
<header class="page__header"><nav class="page__nav main-nav">
<ul>
<li class="nomarker"><h1 class="page__logo"><a href="http://localhost:1313/" class="page__logo-inner">estradiol.cloud</a></h1></li>
<li class="main-nav__item"><a class="nav-main-item active" href="http://localhost:1313/posts/" title="">Posts</a></li>
</ul>
</nav>
</header>
<section class="page__body">
<header class="content__header">
<h1>Hugo on Kubernetes &amp; NGINX</h1>
</header>
<div class="content__body">
<p>i decided to make a website. a static one. this one. with <a href="https://gohugo.io">Hugo</a>. this
is basically as a vanity project so i have some stuff to host in a
<a href="https://kubernetes.io">Kubernetes</a> cluster i&rsquo;m running. the k8s cluster is also as a vanity
project.</p>
<p>because i don&rsquo;t like software, i wanted a way to deploy my site that
2024-02-29 06:49:15 +00:00
doesn&rsquo;t involve much of it. this post is about that.</p>
<h2 id="getting-started">Getting Started</h2>
<p>i built my site by following the straight-forward <em><a href="https://gohugo.io/getting-started">Getting Started</a></em>
guide in the Hugo documentation.</p>
<p>i did <code>hugo new site estradiol.cloud</code>. and then <code>cd estradiol.cloud; git init</code>. and
then i picked a ridiculous theme <a href="https://github.com/joeroe/risotto">&ldquo;inspired by terminal ricing aesthetics&rdquo;</a>,
installing it like <code>git submodule add https://github.com/joeroe/risotto.git themes/risotto; echo &quot;theme = 'risotto'&quot; &gt;&gt; hugo.toml</code>. i appreciate the culinary naming choice.</p>
<p>at this point, my website is basically finished (i also changed the title in <code>hugo.toml</code>).
2024-02-29 06:49:15 +00:00
i probably won&rsquo;t be putting anything on it, so there&rsquo;s no point fiddling with other
details.</p>
<p>about deployment, the guide&rsquo;s <em><a href="https://gohugo.io/getting-started/usage/#deploy-your-site">Basic Usage</a></em> page has this to offer:</p>
<blockquote>
<p>Most of our users deploy their sites using a CI/CD workflow, where a push<sup>1</sup>
to their GitHub or GitLab repository triggers a build and deployment. Popular
providers include AWS Amplify, CloudCannon, Cloudflare Pages, GitHub Pages,
GitLab Pages, and Netlify.</p>
<ol>
<li>The Git repository contains the entire project directory, typically excluding the
public directory because the site is built <em>after</em> the push.</li>
</ol>
</blockquote>
2024-02-29 06:49:15 +00:00
<p>importantly, you can&rsquo;t make a post about deploying this way. <em>everyone</em> deploys
this way. if <em>i</em> deploy this way, this site will have no content.</p>
<p>it also involves some system somewhere that can run Hugo to build the site and push
it to some remote system where my cluster can reach the <code>public/</code> output. i definitely
already need Hugo installed on my workstation if i&rsquo;m going to post anything here
(unlikely), so now i&rsquo;m running Hugo in two places. there&rsquo;s surely going to be
other complex nonsense like webhooks involved.</p>
<!-- raw HTML omitted -->
<hr>
<p>and hang on. let&rsquo;s look at this again:</p>
<blockquote>
<ol>
<li>The Git repository contains the entire project directory, typically excluding the
public directory because the site is built <em>after</em> the push.</li>
</ol>
</blockquote>
<p>you&rsquo;re telling me i&rsquo;m going to build a nice static site and not check the
<em>actual content</em> into version control? couldn&rsquo;t be me.</p>
<h2 id="getting-static">Getting Static</h2>
<p>what if instead i pushed my site to a git repository exactly as i intend to serve it?
2024-02-29 06:49:15 +00:00
then i could shell into my web server, pull the site, and <em>nifty-galifty!</em> isn&rsquo;t this
the way it has <a href="https://www.mikecurato.com/worm-loves-worm">always been done</a>?</p>
2024-02-29 06:49:15 +00:00
<p>one problem is that i don&rsquo;t have a web server, i have a <em>container orchestration
system</em>. there are several upsides to this (few of which are relevant for my project)
2024-02-29 06:49:15 +00:00
but it also means that <em>somehow</em> my content needs to end up in a container, and i
don&rsquo;t want that container to need to retain state across restarts or replicas.</p>
<p>i <em>could</em> run a little pipeline that builds a container wrapping my static site,
pushes it to a registry somewhere my deployments can pull it. all ready to go.
but now i&rsquo;ve got <em>software</em> again: build stages and webhooks and to make matters
worse, now i&rsquo;m hosting and versioning container images.</p>
<!-- raw HTML omitted -->
<p>i don&rsquo;t want any of this.</p>
<hr>
<p>instead, i&rsquo;d like to deploy a popular stock container from a public registry and
deliver my content to it continuously.</p>
<p>as a minimal version of this, i could do:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">Pod</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
2024-02-29 06:49:15 +00:00
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">nginx</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">namespace</span>: <span style="color:#ae81ff">ec</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">labels</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">app.kubernetes.io/instance</span>: <span style="color:#ae81ff">estradiol-cloud</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">app.kubernetes.io/name</span>: <span style="color:#ae81ff">nginx</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
2024-02-29 06:49:15 +00:00
</span></span><span style="display:flex;"><span> <span style="color:#f92672">containers</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">nginx</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">image</span>: <span style="color:#ae81ff">nginx:1.25.4</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">containerPort</span>: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">volumeMounts</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">mountPath</span>: <span style="color:#ae81ff">/app</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">staticsite</span>
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">git-pull</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">image</span>: <span style="color:#ae81ff">bitnami/git</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">command</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#ae81ff">/bin/bash</span>
</span></span><span style="display:flex;"><span> - -<span style="color:#ae81ff">ec</span>
</span></span><span style="display:flex;"><span> - |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> while true; do
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> cd /app &amp;&amp; git -c safe.directory=/app pull origin trunk
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> sleep 60
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> done</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">volumeMounts</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">mountPath</span>: <span style="color:#ae81ff">/app</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">staticsite</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">initContainers</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">git-clone</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">image</span>: <span style="color:#ae81ff">bitnami/git</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">command</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#ae81ff">/bin/bash</span>
</span></span><span style="display:flex;"><span> - -<span style="color:#ae81ff">ec</span>
</span></span><span style="display:flex;"><span> - |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/app
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> cd /tmp/app &amp;&amp; git sparse-checkout init --cone
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> git sparse-checkout set public &amp;&amp; git checkout
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> rm -rf /app &amp;&amp; mv /tmp/app /app</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">volumeMounts</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">mountPath</span>: <span style="color:#ae81ff">/app</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">staticsite</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">volumes</span>:
</span></span><span style="display:flex;"><span> - <span style="color:#f92672">emptyDir</span>: {}
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">staticsite</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">v1</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">ConfigMap</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">labels</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">app.kubernetes.io/instance</span>: <span style="color:#ae81ff">estradiol-cloud</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">app.kubernetes.io/name</span>: <span style="color:#ae81ff">nginx</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">nginx-server-block</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">namespace</span>: <span style="color:#ae81ff">ec</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">data</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">server-block.conf</span>: |-<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> server {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> listen 8080;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> root /app/public;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> index index.html;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> }</span>
</span></span></code></pre></div><!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h2 id="getting-fluxd">Getting Flux&rsquo;d</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">source.toolkit.fluxcd.io/v1beta2</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">HelmRepository</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">bitnami</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">namespace</span>: <span style="color:#ae81ff">default</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">url</span>: <span style="color:#ae81ff">https://charts.bitnami.com/bitnami</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">apiVersion</span>: <span style="color:#ae81ff">source.toolkit.fluxcd.io/v1beta2</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">kind</span>: <span style="color:#ae81ff">HelmRepository</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">metadata</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">name</span>: <span style="color:#ae81ff">bitnami</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">namespace</span>: <span style="color:#ae81ff">default</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">spec</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">url</span>: <span style="color:#ae81ff">https://charts.bitnami.com/bitnami</span>
</span></span></code></pre></div>
</div>
<footer class="content__footer"></footer>
</section>
<section class="page__aside">
<div class="aside__about">
2024-02-29 06:49:15 +00:00
<div class="aside__about">
<h1 class="about__title"></h1>
<p class="about__description">Making vanity projects easy since 2024</p>
</div>
<ul class="aside__social-links">
2024-02-29 06:49:15 +00:00
<li>
<a href="https://hachyderm.io/@no_reply" rel="me" aria-label="Hachyderm" title="Hachyderm"><i class="fa-brands fa-mastodon" aria-hidden="true"></i></a>&nbsp;
</li>
<li>
<a href="https://gitlab.com/no_reply" rel="me" aria-label="GitLab" title="GitLab"><i class="fa-brands fa-gitlab" aria-hidden="true"></i></a>&nbsp;
</li>
<li>
<a href="https://github.com/no-reply" rel="me" aria-label="GitHub" title="GitHub"><i class="fa-brands fa-github" aria-hidden="true"></i></a>&nbsp;
</li>
</ul>
</div>
<hr>
<div class="aside__content">
<p>
2024-02-28
</p>
</div>
</section>
2024-02-29 06:49:15 +00:00
<footer class="page__footer"></footer>
</div>
</body>
</html>