diff --git a/content/posts/hugo-on-k8s-nginx.md b/content/posts/hugo-on-k8s-nginx.md new file mode 100644 index 0000000..8f3761f --- /dev/null +++ b/content/posts/hugo-on-k8s-nginx.md @@ -0,0 +1,179 @@ ++++ +title = 'Hugo on Kubernetes & NGINX' +date = 2024-02-28T15:35:46-08:00 +draft = true ++++ + +i decided to make a website. a static one. this one. with [Hugo][hugo]. this +is basically as a vanity project so i have some stuff to host in a +[Kubernetes][k8s] cluster i'm running. the k8s cluster is also as a vanity +project. + +because i don't like software, i wanted a way to deploy my site that +doesn't involve much. this post is about that. + +## Getting Started + +i built my site by following the straight-forward _[Getting Started][hugo-started]_ +guide in the Hugo documentation. + +i did `hugo new site estradiol.cloud`. and then `cd estradiol.cloud; git init`. and +then i picked a ridiculous theme ["inspired by terminal ricing aesthetics"][risotto], +installing it like `git submodule add https://github.com/joeroe/risotto.git themes/risotto; echo "theme = 'risotto'" >> hugo.toml`. i appreciate the culinary naming choice. + +at this point, my website is basically finished (i also changed the title in `hugo.toml`). +i probably won't be putting much on it, so there's no point fussing with other details. + +about deployment, the guide's _[Basic Usage][hugo-deploy]_ page has this to offer: + +> Most of our users deploy their sites using a CI/CD workflow, where a push{{< sup "1" >}} +> 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. +> +> 1. The Git repository contains the entire project directory, typically excluding the +> public directory because the site is built _after_ the push. + +importantly, you can't make a post about depoying this way. _everyone_ deploys +this way. + +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 it. i definitely already need +Hugo installed on my workstation if i'm going to post anything here (unlikely), so +now i'm running Hugo in two places. there's definitely going to be other complex +nonsense like webhooks involved. + +and hang on. let's look at this again: + +> 1. The Git repository contains the entire project directory, typically excluding the +> public directory because the site is built _after_ the push. + +you're telling me i'm going to build a nice static site and not check the +_actual content_ into version control? couldn't be me. + +## Getting Static + +what if instead i pushed my site to a git repository exactly as i intend to serve it? +then i could shell into my webserver, pull the site, and _nifty-galifty!_ isn't this +the way it has [always been done][worm]? + +one problem is that i don't have a webserver, i have a _container orchestration +system_. there are several upsides to this (few of which are relevant for my project) +but it demands i get a bit more clever. i _could_ run a little pipeline that builds a +container wrapping my static site, pushes it to a registry somewhere so my deployments +can pull it, all ready to go. but now i've got _software_ again; build stages and webhooks +and i'm hosting and versioning container images. i don't want any of this. + + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: estradiol-cloud + app.kubernetes.io/name: nginx + name: web-nginx + namespace: estradiol-cloud +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: estradiol-cloud + app.kubernetes.io/name: nginx + template: + metadata: + labels: + app.kubernetes.io/instance: estradiol-cloud + app.kubernetes.io/name: nginx + spec: + containers: + - name: git-repo-syncer + image: docker.io/bitnami/git:2.43.2-debian-12-r2 + imagePullPolicy: IfNotPresent + command: + - /bin/bash + - -ec + - | + while true; do + cd /app && git -c safe.directory=/app pull origin trunk + sleep 60 + done + volumeMounts: + - mountPath: /app + name: staticsite + - name: nginx + image: docker.io/bitnami/nginx:1.25.4-debian-12-r2 + imagePullPolicy: IfNotPresent + env: + - name: NGINX_HTTP_PORT_NUMBER + value: "8080" + livenessProbe: + tcpSocket: + port: http + readinessProbe: + tcpSocket: + port: http + ports: + - containerPort: 8080 + name: http + protocol: TCP + volumeMounts: + - mountPath: /opt/bitnami/nginx/conf/server_blocks + name: nginx-server-block + - mountPath: /app + name: staticsite + initContainers: + - name: git-clone-repository + image: docker.io/bitnami/git:2.43.2-debian-12-r2 + imagePullPolicy: IfNotPresent + command: + - /bin/bash + - -ec + - | + [[ -f "/opt/bitnami/scripts/git/entrypoint.sh" ]] && source "/opt/bitnami/scripts/git/entrypoint.sh" + git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/app + [[ "$?" -eq 0 ]] && cd /tmp/app && git sparse-checkout init --cone && git sparse-checkout set public && git checkout && shopt -s dotglob && rm -rf /app/* && mv /tmp/app/* /app/ + volumeMounts: + - mountPath: /app + name: staticsite + restartPolicy: Always + terminationGracePeriodSeconds: 30 + volumes: + - configMap: + defaultMode: 420 + name: web-nginx-server-block + name: nginx-server-block + - emptyDir: {} + name: staticsite +``` + +## Getting Flux'd + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: bitnami + namespace: default +spec: + url: https://charts.bitnami.com/bitnami +``` + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: bitnami + namespace: default +spec: + url: https://charts.bitnami.com/bitnami +``` + + + +[hugo]: https://gohugo.io +[hugo-deploy]: https://gohugo.io/getting-started/usage/#deploy-your-site +[hugo-started]: https://gohugo.io/getting-started +[k8s]: https://kubernetes.io +[risotto]: https://github.com/joeroe/risotto +[worm]: https://www.mikecurato.com/worm-loves-worm diff --git a/hugo.toml b/hugo.toml index fea7ae5..cd64ab4 100644 --- a/hugo.toml +++ b/hugo.toml @@ -2,3 +2,8 @@ baseURL = 'https://estradiol.cloud/' languageCode = 'en-us' title = 'estradiol.cloud' theme = 'risotto' +[menus] +[[menus.main]] + name = 'Posts' + pageRef = '/posts' + weight = 20 diff --git a/layouts/shortcodes/sub.html b/layouts/shortcodes/sub.html new file mode 100644 index 0000000..e1d97d9 --- /dev/null +++ b/layouts/shortcodes/sub.html @@ -0,0 +1 @@ +{{ .Get 0 | markdownify }} diff --git a/layouts/shortcodes/sup.html b/layouts/shortcodes/sup.html new file mode 100644 index 0000000..665c317 --- /dev/null +++ b/layouts/shortcodes/sup.html @@ -0,0 +1 @@ +{{ .Get 0 | markdownify }} diff --git a/public/categories/index.html b/public/categories/index.html index be11a91..c801c1e 100644 --- a/public/categories/index.html +++ b/public/categories/index.html @@ -1,2 +1,2 @@