more work on the meta post

This commit is contained in:
tamsin woo 2024-02-29 23:48:47 -08:00
parent a11bfa58ec
commit 459dfcf6aa
23 changed files with 1701 additions and 959 deletions

18
.d2/flux-seq.d2 Normal file
View File

@ -0,0 +1,18 @@
flux deployment: {
shape: sequence_diagram
laptop: My Laptop
gitlab: Git Repo
k8s: Kubernetes
flux: Flux Kustomize Controller
fluxhelm: Flux Helm Controller
laptop -> gitlab: git push
gitlab <- flux: git pull
k8s <- flux: apply HelmRelease
k8s."HelmRelease"
fluxhelm -> k8s: poll for HelmRelease resources
fluxhelm -> k8s: `helm upgrade`
k8s."NGINX Deployment, etc..."
}

38
.d2/hugo-gitlab-pages.d2 Normal file
View File

@ -0,0 +1,38 @@
title: |md
# deploy w/ GitHub pages & actions
| {
shape: text
near: top-center
}
my laptop {
icon: https://icons.terrastruct.com/tech%2Flaptop.svg
near: center-left
}
my laptop -> GitHub.repo: git push
GitHub {
icon: https://icons.terrastruct.com/social%2F039-github.svg
repo <- runner.build job: pull
runner {
build job
deploy job
}
events api <- runner: long poll
runner.build job -> artifact storage.pages artifact: uses
runner.deploy job -> artifact storage.pages artifact: uses
runner.deploy job -> pages.Hugo site: deploys
artifact storage {
pages artifact
}
pages {
Hugo site
}
}

View File

@ -3,29 +3,34 @@ title = 'Hugo on Kubernetes & NGINX'
date = 2024-02-28T15:35:46-08:00
draft = true
series = ['wtf']
categories = ['Tech']
tags = ['meta', 'k8s']
categories = ['Tutorial']
tags = ['meta', 'k8s', 'flux', 'hugo']
toc = 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.
i decided to make a website. a static one. this one. with [Hugo][hugo]. the
main reason i have for this is 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 of it. this post is about that.
because i don't like software, i wanted a way to deploy my site that doesn't
involve much of it. 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 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.
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`.[^1]
at this point, my website is basically finished (i also changed the title in `hugo.toml`).
i probably won't be putting anything on it, so there's no point fiddling with other
[^1]: i appreciate the culinary theme.
at this point, my website is basically finished (i also changed the title in
`hugo.toml`). i probably won't be putting anything on it, so there's no point fiddling with other
details.
about deployment, the guide's _[Basic Usage][hugo-deploy]_ page has this to offer:
@ -42,12 +47,14 @@ importantly, you can't make a post about deploying this way. _everyone_ deploys
this way. if _i_ deploy this way, this site will have no content.
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 `public/` output. 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 surely going to be
other complex nonsense like webhooks involved.
it to some remote system where my cluster can reach the compiled site. i definitely
already need Hugo installed on my workstation if i'm going to post anything.[^2]
so now i'm running Hugo in two places. there's surely going to be other complex
nonsense like webhooks involved.
<!-- diagram ?? -->
[^2]: unlikely.
![diagram: deploy w/ GitHub pages & actions](images/hugo-github-pages.svg)
----
@ -61,37 +68,109 @@ _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 web server, pull the site, and _nifty-galifty!_ isn't this
the way it has [always been done][worm]?
suppose i instead checked my content into git exactly as i intend to serve it?
then i could shell into my server box, pull the site, and _nifty-galifty!_ isn't
this the way it has [always been done][worm-love]?
one problem is that i don't have a web server, i have a _container orchestration
system_. there are several upsides to this (few of which are relevant for my project)
but it also means that _somehow_ my content needs to end up in a container, and i
don't want that container to need to retain state across restarts or replicas.
i _could_ run a little pipeline that builds a container wrapping my static site,
my problem is that i don't have a server box. i have a _container orchestration
system_. there are several upsides to this[^3] but it means that _somehow_ my
generated content needs to end up in a container. because [Pods][k8s-pods] are
ephemeral and i'd like to run my site with horizontal scalability[^4], i don't
want my container to need to retain runtime state across restarts or replicas.
[^3]: few of which could be considered relevant for my project.
[^4]: i absolutely will not need this
i _could_ run a little pipeline that builds a container wrapping my content and
pushes it to a registry somewhere my deployments can pull it. all ready to go.
but now i've got _software_ again: build stages and webhooks and to make matters
but now i've got _software_ again: build stages and webhooks and, to make matters
worse, now i'm hosting and versioning container images.
<!-- diagram ?? -->
![diagram: deploy w/ container build](/images/hugo-container-build.svg)
i don't want any of this.
i don't want any of this. i just want to put some HTML and static assets behind a
web server.
---
instead, i'd like to deploy a popular stock container from a public registry and
deliver my content to it continuously.
instead, i'd like to deploy a popular container image from a public registry
and deliver my content to it continuously.
as a minimal version of this, i could do:
a minimal setup to achieve this might look like:
```yaml
- a `Pod` with:
- an `nginx` container to serve the content;
- a `git-pull` sidecar that loops, pulling the git content;
- an `initContainer` to do the initial checkout;
- an `emptyDir` volume to share between the containers.
- a `ConfigMap` to store the nginx config.
![diagram: minimal pod/configmap setup](/images/hugo-minimal-pod-setup.svg)
i use `git sparse-checkout` to avoid pulling repository contents i don't want
to serve out:
```bash
# git-clone command
git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/www;
cd /tmp/www;
git sparse-checkout init --cone;
git sparse-checkout set public;
git checkout;
shopt -s dotglob
mv /tmp/www/* /www
```
script up my `git pull` loop:
```bash
# git-pull command
while true; do
cd /www && git -c safe.directory=/www pull origin trunk
sleep 60
done
```
and configure `nginx` to use `public/` as root:
```txt
# ConfigMap; data: default.conf
server {
listen 80;
location / {
root /www/public;
index index.html;
}
}
```
the rest of this is pretty much boilerplate:
{{< code-details summary="`kubectl apply -f estradiol-cloud.yaml`" lang="yaml" details=`
# estradiol-cloud.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/instance: estradiol-cloud
app.kubernetes.io/name: nginx
name: nginx-server-block
data:
default.conf: |-
server {
listen 80;
location / {
root /www/public;
index index.html;
}
}
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: ec
labels:
app.kubernetes.io/instance: estradiol-cloud
app.kubernetes.io/name: nginx
@ -102,8 +181,10 @@ spec:
ports:
- containerPort: 80
volumeMounts:
- mountPath: /app
name: staticsite
- mountPath: /www
name: www
- mountPath: /etc/nginx/conf.d
name: nginx-server-block
- name: git-pull
image: bitnami/git
command:
@ -111,159 +192,163 @@ spec:
- -ec
- |
while true; do
cd /app && git -c safe.directory=/app pull origin trunk
cd /www && git -c safe.directory=/www pull origin trunk
sleep 60
done
volumeMounts:
- mountPath: /app
name: staticsite
- mountPath: /www
name: www
initContainers:
- name: git-clone
image: bitnami/git
command:
- /bin/bash
- -ec
- -c
- |
git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/app
cd /tmp/app && git sparse-checkout init --cone
git sparse-checkout set public && git checkout
rm -rf /app && mv /tmp/app /app
shopt -s dotglob
git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/www;
cd /tmp/www;
p git sparse-checkout init --cone;
git sparse-checkout set public;
git checkout;
mv /tmp/www/* /www
volumeMounts:
- mountPath: /app
name: staticsite
- mountPath: /www
name: www
volumes:
- emptyDir: {}
name: staticsite
- name: www
emptyDir: {}
- name: nginx-server-block
configMap:
name: nginx-server-block
` >}}
---
apiVersion: v1
kind: ConfigMap
my Hugo workflow now looks like:
1. make changes to source;
1. run `hugo --gc --minify`;[^7]
1. commit & push.
the only active process from this point is my little control loop running `git pull`.
[^7]: i added `disableHTML = true` to `[minify]` configuration in `hugo.toml`
to keep HTML diffs readable.
## Getting Web
my Pod is running. everything is great. if i want to browse to my website i
just need to setup a [port-forward][k8s-port]
TK: YAML counts as software.
conveniently, [Bitnami][bitnami] maintains a [Helm][helm] Chart that
![diagram: helm setup](/images/hugo-helm-setup.svg)
## Getting Flux'd
by this point i'm pretty `git push`-pilled and i'm thinking i don't much like
having this `helm` client software installed on my laptop.
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
labels:
app.kubernetes.io/instance: estradiol-cloud
app.kubernetes.io/name: nginx
name: nginx-server-block
namespace: ec
data:
server-block.conf: |-
name: bitnami
namespace: default
spec:
url: https://charts.bitnami.com/bitnami
```
{{< code-details summary="`release.yaml`" lang="yaml" details=`
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: web
namespace: estradiol-cloud
spec:
interval: 5m
chart:
spec:
chart: nginx
version: '15.12.2'
sourceRef:
kind: HelmRepository
name: bitnami
namespace: default
interval: 1m
values:
cloneStaticSiteFromGit:
enabled: true
repository: "https://code.estradiol.cloud/tamsin/estradiol.cloud.git"
branch: trunk
gitClone:
command:
- /bin/bash
- -ec
- |
[[ -f "/opt/bitnami/scripts/git/entrypoint.sh" ]] && source "/opt/bitnami/scripts/git/entrypoint.sh"
git clone {{ .Values.cloneStaticSiteFromGit.repository }} --no-checkout --branch {{ .Values.cloneStaticSiteFromGit.branch }} /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/
ingress:
enabled: true
hostname: estradiol.cloud
ingressClassName: nginx
tls: true
annotations: {
cert-manager.io/cluster-issuer: letsencrypt-prod
}
serverBlock: |-
server {
listen 8080;
root /app/public;
index index.html;
}
```
<!-- ```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
```
service:
type: ClusterIP
`>}}
![Scenario 1: Across columns](images/flux-seq.svg)
## A Note About Software
at this point i'm forced to admit there's still a lot of software involved in this.
setting aside the stuff that provisions and scales my cluster nodes, i have:
- `nginx` (running from a stock image);
- `git` & `bash` (running from a stock image);
- a remote git server (i'm running `gitea`[^8], but github dot com is fine here);
- Kubernetes (oops!);
- `fluxcd`;
- especially `kustomize-controller` and `helm-controller`;
- `nginx-ingress` controller;
- the `bitnami/nginx` Helm chart;
[^8]: because i'm running `gitea` in my cluster and i want to avoid a circular
dependency for my `flux` source repository, i also depend on GitLab dot com.
i get to maintain my two `bash` scripts for `git-clone` and `git-pull`, my
NGINX config, and a couple of blobs of YAML.
at least there are no webhooks.
---
_fin_
[bitnami]: https://bitnami.com/
[helm]: https://helm.sh
[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
[k8s-init]: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
[k8s-pods]: https://kubernetes.io/docs/concepts/workloads/pods/
[k8s-port]: https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/
[k8s-pv]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
[risotto]: https://github.com/joeroe/risotto
[worm]: https://www.mikecurato.com/worm-loves-worm
[worm-love]: https://www.mikecurato.com/worm-loves-worm

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 108 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -0,0 +1,356 @@
+++
title = 'Hugo on Kubernetes & NGINX'
date = 2024-02-28T15:35:46-08:00
draft = true
series = ['wtf']
categories = ['Tutorial']
tags = ['meta', 'k8s', 'flux', 'hugo']
toc = true
+++
i decided to make a website. a static one. this one. with [Hugo][hugo]. the
main reason i have for this is 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 of it. 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`.[^1]
[^1]: i appreciate the culinary theme.
at this point, my website is basically finished (i also changed the title in
`hugo.toml`). i probably won't be putting anything on it, so there's no point fiddling 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 deploying this way. _everyone_ deploys
this way. if _i_ deploy this way, this site will have no content.
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 compiled site. i definitely
already need Hugo installed on my workstation if i'm going to post anything.[^2]
so now i'm running Hugo in two places. there's surely going to be other complex
nonsense like webhooks involved.
[^2]: unlikely.
![diagram: deploy w/ GitHub pages & actions](/images/hugo-github-pages.svg)
----
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
suppose i instead checked my content into git exactly as i intend to serve it?
then i could shell into my server box, pull the site, and _nifty-galifty!_ isn't
this the way it has [always been done][worm-love]?
my problem is that i don't have a server box. i have a _container orchestration
system_. there are several upsides to this[^3] but it means that _somehow_ my
generated content needs to end up in a container. because [Pods][k8s-pods] are
ephemeral and i'd like to run my site with horizontal scalability[^4], i don't
want my container to need to retain runtime state across restarts or replicas.
[^3]: few of which could be considered relevant for my project.
[^4]: i absolutely will not need this
i _could_ run a little pipeline that builds a container wrapping my content and
pushes it to a registry somewhere my deployments can pull it. all ready to go.
but now i've got _software_ again: build stages and webhooks and, to make matters
worse, now i'm hosting and versioning container images.
![diagram: deploy w/ container build](/images/hugo-container-build.svg)
i don't want any of this. i just want to put some HTML and static assets behind a
web server.
---
instead, i'd like to deploy a popular container image from a public registry
and deliver my content to it continuously.
a minimal setup to achieve this might look like:
- a `Pod` with:
- an `nginx` container to serve the content;
- a `git-pull` sidecar that loops, pulling the git content;
- an `initContainer` to do the initial checkout;
- an `emptyDir` volume to share between the containers.
- a `ConfigMap` to store the nginx config.
![diagram: minimal pod/configmap setup](/images/hugo-minimal-pod-setup.svg)
i use `git sparse-checkout` to avoid pulling repository contents i don't want
to serve out:
```bash
# git-clone command
git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/www;
cd /tmp/www;
git sparse-checkout init --cone;
git sparse-checkout set public;
git checkout;
shopt -s dotglob
mv /tmp/www/* /www
```
script up my `git pull` loop:
```bash
# git-pull command
while true; do
cd /www && git -c safe.directory=/www pull origin trunk
sleep 60
done
```
and configure `nginx` to use `public/` as root:
```txt
# ConfigMap; data: default.conf
server {
listen 80;
location / {
root /www/public;
index index.html;
}
}
```
the rest of this is pretty much boilerplate:
{{< code-details summary="`kubectl apply -f estradiol-cloud.yaml`" lang="yaml" details=`
# estradiol-cloud.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/instance: estradiol-cloud
app.kubernetes.io/name: nginx
name: nginx-server-block
data:
default.conf: |-
server {
listen 80;
location / {
root /www/public;
index index.html;
}
}
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app.kubernetes.io/instance: estradiol-cloud
app.kubernetes.io/name: nginx
spec:
containers:
- name: nginx
image: nginx:1.25.4
ports:
- containerPort: 80
volumeMounts:
- mountPath: /www
name: www
- mountPath: /etc/nginx/conf.d
name: nginx-server-block
- name: git-pull
image: bitnami/git
command:
- /bin/bash
- -ec
- |
while true; do
cd /www && git -c safe.directory=/www pull origin trunk
sleep 60
done
volumeMounts:
- mountPath: /www
name: www
initContainers:
- name: git-clone
image: bitnami/git
command:
- /bin/bash
- -c
- |
shopt -s dotglob
git clone https://code.estradiol.cloud/tamsin/estradiol.cloud.git --no-checkout --branch trunk /tmp/www;
cd /tmp/www;
p git sparse-checkout init --cone;
git sparse-checkout set public;
git checkout;
mv /tmp/www/* /www
volumeMounts:
- mountPath: /www
name: www
volumes:
- name: www
emptyDir: {}
- name: nginx-server-block
configMap:
name: nginx-server-block
` >}}
---
my Hugo workflow now looks like:
1. make changes to source;
1. run `hugo --gc --minify`;[^7]
1. commit & push.
the only active process from this point is my little control loop running `git pull`.
[^7]: i added `disableHTML = true` to `[minify]` configuration in `hugo.toml`
to keep HTML diffs readable.
## Getting Web
my Pod is running. everything is great. if i want to browse to my website i
just need to setup a [port-forward][k8s-port]
TK: YAML counts as software.
conveniently, [Bitnami][bitnami] maintains a [Helm][helm] Chart that
![diagram: helm setup](/images/hugo-helm-setup.svg)
## Getting Flux'd
by this point i'm pretty `git push`-pilled and i'm thinking i don't much like
having this `helm` client software installed on my laptop.
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: bitnami
namespace: default
spec:
url: https://charts.bitnami.com/bitnami
```
{{< code-details summary="`release.yaml`" lang="yaml" details=`
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: web
namespace: estradiol-cloud
spec:
interval: 5m
chart:
spec:
chart: nginx
version: '15.12.2'
sourceRef:
kind: HelmRepository
name: bitnami
namespace: default
interval: 1m
values:
cloneStaticSiteFromGit:
enabled: true
repository: "https://code.estradiol.cloud/tamsin/estradiol.cloud.git"
branch: trunk
gitClone:
command:
- /bin/bash
- -ec
- |
[[ -f "/opt/bitnami/scripts/git/entrypoint.sh" ]] && source "/opt/bitnami/scripts/git/entrypoint.sh"
git clone {{ .Values.cloneStaticSiteFromGit.repository }} --no-checkout --branch {{ .Values.cloneStaticSiteFromGit.branch }} /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/
ingress:
enabled: true
hostname: estradiol.cloud
ingressClassName: nginx
tls: true
annotations: {
cert-manager.io/cluster-issuer: letsencrypt-prod
}
serverBlock: |-
server {
listen 8080;
root /app/public;
index index.html;
}
service:
type: ClusterIP
`>}}
{{ with .Resources.GetMatch "hugo-flux-seq.svg" }}
<img src="data:{{ .MediaType.Type }};base64,{{ .Content | base64Encode }}">
{{ end }}
## A Note About Software
at this point i'm forced to admit there's still a lot of software involved in this.
setting aside the stuff that provisions and scales my cluster nodes, i have:
- `nginx` (running from a stock image);
- `git` & `bash` (running from a stock image);
- a remote git server (i'm running `gitea`[^8], but github dot com is fine here);
- Kubernetes (oops!);
- `fluxcd`;
- especially `kustomize-controller` and `helm-controller`;
- `nginx-ingress` controller;
- the `bitnami/nginx` Helm chart;
[^8]: because i'm running `gitea` in my cluster and i want to avoid a circular
dependency for my `flux` source repository, i also depend on GitLab dot com.
i get to maintain my two `bash` scripts for `git-clone` and `git-pull`, my
NGINX config, and a couple of blobs of YAML.
at least there are no webhooks.
---
_fin_
[bitnami]: https://bitnami.com/
[helm]: https://helm.sh
[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
[k8s-init]: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
[k8s-pods]: https://kubernetes.io/docs/concepts/workloads/pods/
[k8s-port]: https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/
[k8s-pv]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
[risotto]: https://github.com/joeroe/risotto
[worm-love]: https://www.mikecurato.com/worm-loves-worm

View File

@ -7,7 +7,7 @@ paginate = 3
[params]
[params.about]
title = ""
description = "Making vanity projects easy since 2024"
description = ""
[[params.socialLinks]]
icon = "fa-brands fa-mastodon"
@ -27,6 +27,14 @@ url = "https://github.com/no-reply"
[params.theme]
palette = "material"
[markup]
# Table of contents
# Add toc = true to content front matter to enable
[markup.tableOfContents]
startLevel = 2
endLevel = 3
ordered = true
[menus]
[[menus.main]]
name = 'Posts'

View File

@ -0,0 +1,25 @@
{{ define "main" }}
<header class="content__header">
<h1>{{ .Title | markdownify }}</h1>
</header>
<div class="content__body">
{{ .Content }}
</div>
<footer class="content__footer"></footer>
{{ end }}
{{define "aside" }}
{{ if .Params.description }}<p>{{ .Params.description }}</p>{{ end }}
{{ if or (.Params.author) (.Params.date) }}
<p>
{{ if .Params.author }}By {{ .Params.author }}{{ if .Date }}, {{ end }}{{ end }}
{{ if .Date }}{{ .Date.Format "2006-01-02" }}{{ end }}
</p>
{{ end }}
{{ if and (.Params.toc) (.TableOfContents) }}
<hr>
{{ .Title }}:
{{ .TableOfContents }}
{{ end }}
{{ end }}

View File

@ -0,0 +1,4 @@
<details>
<summary>{{ .Get "summary" | markdownify }}</summary>
{{ printf "```%s%s```" (.Get "lang") (.Get "details") | markdownify}}
</details>

View File

@ -0,0 +1,4 @@
<details>
<summary>{{ .Get "summary" | markdownify }}</summary>
{{ .Get "details" | markdownify }}
</details>

View File

@ -2,7 +2,7 @@
<html lang="en">
<head><title>Categories &ndash; estradiol.cloud</title>
<meta name="description" content="Making vanity projects easy since 2024">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"/>
@ -60,7 +60,7 @@
<h1 class="about__title"></h1>
<p class="about__description">Making vanity projects easy since 2024</p>
</div>

View File

@ -1,98 +0,0 @@
<!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>Tech &ndash; estradiol.cloud</title>
<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" />
<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" href="http://localhost:1313/posts/" title="">Posts</a></li>
</ul>
</nav>
</header>
<section class="page__body">
<h1 id="tech">Tech</h1>
<ul>
<li><a href="http://localhost:1313/posts/hugo-on-k8s-nginx/">Hugo on Kubernetes &amp; NGINX</a></li>
</ul>
</section>
<section class="page__aside">
<div class="aside__about">
<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">
<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">
</div>
</section>
<footer class="page__footer"></footer>
</div>
</body>
</html>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Tech on estradiol.cloud</title>
<link>http://localhost:1313/categories/tech/</link>
<description>Recent content in Tech on estradiol.cloud</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Wed, 28 Feb 2024 15:35:46 -0800</lastBuildDate>
<atom:link href="http://localhost:1313/categories/tech/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Hugo on Kubernetes &amp; NGINX</title>
<link>http://localhost:1313/posts/hugo-on-k8s-nginx/</link>
<pubDate>Wed, 28 Feb 2024 15:35:46 -0800</pubDate>
<guid>http://localhost:1313/posts/hugo-on-k8s-nginx/</guid>
<description>i decided to make a website. a static one. this one. with Hugo. this is basically as a vanity project so i have some stuff to host in a Kubernetes cluster i&amp;rsquo;m running. the k8s cluster is also as a vanity project.&#xA;because i don&amp;rsquo;t like software, i wanted a way to deploy my site that doesn&amp;rsquo;t involve much of it. this post is about that.&#xA;Getting Started i built my site by following the straight-forward Getting Started guide in the Hugo documentation.</description>
</item>
</channel>
</rss>

View File

@ -3,7 +3,7 @@
<head>
<meta name="generator" content="Hugo 0.123.5"><title>estradiol.cloud &ndash; estradiol.cloud</title>
<meta name="description" content="Making vanity projects easy since 2024">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"/>
@ -54,7 +54,7 @@
<h1 class="about__title"></h1>
<p class="about__description">Making vanity projects easy since 2024</p>
</div>

View File

@ -1,325 +0,0 @@
<!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>
<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" />
<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
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>).
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>
<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?
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>
<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)
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>:
</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>:
</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">
<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">
<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>
<footer class="page__footer"></footer>
</div>
</body>
</html>

View File

@ -2,7 +2,7 @@
<html lang="en">
<head><title>Posts &ndash; estradiol.cloud</title>
<meta name="description" content="Making vanity projects easy since 2024">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"/>
@ -60,7 +60,7 @@
<h1 class="about__title"></h1>
<p class="about__description">Making vanity projects easy since 2024</p>
</div>

View File

@ -2,7 +2,7 @@
<html lang="en">
<head><title>Tags &ndash; estradiol.cloud</title>
<meta name="description" content="Making vanity projects easy since 2024">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8"/>
@ -60,7 +60,7 @@
<h1 class="about__title"></h1>
<p class="about__description">Making vanity projects easy since 2024</p>
</div>

View File

@ -1,98 +0,0 @@
<!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>K8s &ndash; estradiol.cloud</title>
<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" />
<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" href="http://localhost:1313/posts/" title="">Posts</a></li>
</ul>
</nav>
</header>
<section class="page__body">
<h1 id="k8s">K8s</h1>
<ul>
<li><a href="http://localhost:1313/posts/hugo-on-k8s-nginx/">Hugo on Kubernetes &amp; NGINX</a></li>
</ul>
</section>
<section class="page__aside">
<div class="aside__about">
<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">
<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">
</div>
</section>
<footer class="page__footer"></footer>
</div>
</body>
</html>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>K8s on estradiol.cloud</title>
<link>http://localhost:1313/tags/k8s/</link>
<description>Recent content in K8s on estradiol.cloud</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Wed, 28 Feb 2024 15:35:46 -0800</lastBuildDate>
<atom:link href="http://localhost:1313/tags/k8s/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Hugo on Kubernetes &amp; NGINX</title>
<link>http://localhost:1313/posts/hugo-on-k8s-nginx/</link>
<pubDate>Wed, 28 Feb 2024 15:35:46 -0800</pubDate>
<guid>http://localhost:1313/posts/hugo-on-k8s-nginx/</guid>
<description>i decided to make a website. a static one. this one. with Hugo. this is basically as a vanity project so i have some stuff to host in a Kubernetes cluster i&amp;rsquo;m running. the k8s cluster is also as a vanity project.&#xA;because i don&amp;rsquo;t like software, i wanted a way to deploy my site that doesn&amp;rsquo;t involve much. this post is about that.&#xA;Getting Started i built my site by following the straight-forward Getting Started guide in the Hugo documentation.</description>
</item>
</channel>
</rss>

View File

@ -1,98 +0,0 @@
<!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>Meta &ndash; estradiol.cloud</title>
<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" />
<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" href="http://localhost:1313/posts/" title="">Posts</a></li>
</ul>
</nav>
</header>
<section class="page__body">
<h1 id="meta">Meta</h1>
<ul>
<li><a href="http://localhost:1313/posts/hugo-on-k8s-nginx/">Hugo on Kubernetes &amp; NGINX</a></li>
</ul>
</section>
<section class="page__aside">
<div class="aside__about">
<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">
<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">
</div>
</section>
<footer class="page__footer"></footer>
</div>
</body>
</html>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Meta on estradiol.cloud</title>
<link>http://localhost:1313/tags/meta/</link>
<description>Recent content in Meta on estradiol.cloud</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Wed, 28 Feb 2024 15:35:46 -0800</lastBuildDate>
<atom:link href="http://localhost:1313/tags/meta/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Hugo on Kubernetes &amp; NGINX</title>
<link>http://localhost:1313/posts/hugo-on-k8s-nginx/</link>
<pubDate>Wed, 28 Feb 2024 15:35:46 -0800</pubDate>
<guid>http://localhost:1313/posts/hugo-on-k8s-nginx/</guid>
<description>i decided to make a website. a static one. this one. with Hugo. this is basically as a vanity project so i have some stuff to host in a Kubernetes cluster i&amp;rsquo;m running. the k8s cluster is also as a vanity project.&#xA;because i don&amp;rsquo;t like software, i wanted a way to deploy my site that doesn&amp;rsquo;t involve much. this post is about that.&#xA;Getting Started i built my site by following the straight-forward Getting Started guide in the Hugo documentation.</description>
</item>
</channel>
</rss>

View File

@ -1,98 +0,0 @@
<!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>Tech &ndash; estradiol.cloud</title>
<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" />
<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" href="http://localhost:1313/posts/" title="">Posts</a></li>
</ul>
</nav>
</header>
<section class="page__body">
<h1 id="tech">Tech</h1>
<ul>
<li><a href="http://localhost:1313/posts/hugo-on-k8s-nginx/">Hugo on Kubernetes &amp; NGINX</a></li>
</ul>
</section>
<section class="page__aside">
<div class="aside__about">
<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">
<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">
</div>
</section>
<footer class="page__footer"></footer>
</div>
</body>
</html>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Tech on estradiol.cloud</title>
<link>http://localhost:1313/tags/tech/</link>
<description>Recent content in Tech on estradiol.cloud</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<lastBuildDate>Wed, 28 Feb 2024 15:35:46 -0800</lastBuildDate>
<atom:link href="http://localhost:1313/tags/tech/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Hugo on Kubernetes &amp; NGINX</title>
<link>http://localhost:1313/posts/hugo-on-k8s-nginx/</link>
<pubDate>Wed, 28 Feb 2024 15:35:46 -0800</pubDate>
<guid>http://localhost:1313/posts/hugo-on-k8s-nginx/</guid>
<description>i decided to make a website. a static one. this one. with Hugo. this is basically as a vanity project so i have some stuff to host in a Kubernetes cluster i&amp;rsquo;m running. the k8s cluster is also as a vanity project.&#xA;because i don&amp;rsquo;t like software, i wanted a way to deploy my site that doesn&amp;rsquo;t involve much. this post is about that.&#xA;Getting Started i built my site by following the straight-forward Getting Started guide in the Hugo documentation.</description>
</item>
</channel>
</rss>