Blog

All my posts and notes. (Browse by tags)

Remaking My Blog From Scratch

2025 Edition

Posts | 2025-10-26 | 10 min read
#development #gitlab #hugo
Series: Tech Behind the Blog

I’ve been blogging in one form or another for 5 years now.

All blogs and other online publishing adventures had one thing in common: I barely knew what I was doing, using components I never learned properly.

I wanted to change that! And with the benefit of hindsight I will now take you on this adventure with me.

Read more…

Hugo Environment Variable Magic

Notes | 2025-10-22 (updated 2025-10-25) | 1 min read
#hugo #ssg

You can overwrite hugo configuration values with environment variables!

Read more…

Hacking Comments Into JSON

Notes | 2025-09-19 (updated 2025-10-25) | 1 min read
#json

JSON does not natively support comments, which is OK, but sometimes a comment could really help.

If the application loading the JSON does not care about additional keys we can simply add a key with our favorite comment indicator like // or #.

{
  "//": "This setting enables not just A, but somehow also B",
  "enable_feature_a": true
}

While this works consider using a different file format better suited for configuration.

Read more…

Finding PID Everywhere

the proc virtual filesystem

Notes | 2025-09-19 (updated 2025-10-25) | 1 min read
#container #linux #sysadmin

Usually at least one of those is present on any system

But sometimes the usual suspects are not available, especially in minimal containers.

But there is another, more low level, way that works: /proc

This is a virtual filesystem provided by the kernel about running processes.

So to mirror something like this:

$ ps aux |grep sleep
    5 root      0:00 sleep 1000
   21 root      0:00 sleep 10000000
   36 root      0:00 grep sleep

We could do:

Read more…

Replace item in list with Kustomize

Notes | 2025-09-16 (updated 2025-10-25) | 1 min read
#k8s #kustomize

Kubernetes resources have quite a lot of lists in them and replacing an item in such lists is quite easy using kustomize patches with op: replace.

Replacing a specific list item safely however is not as obvious as the order of items could change, leading to a technically valid but practically incorrect manifest.

Read more…

Easy Backlink Check

Notes | 2025-09-08 (updated 2025-10-25) | 1 min read
#seo

There are loads of better ways to do this using Google Search Console / Bing Webmaster Tools / ahrefs and similar tools.

Arguably these might be a bit too much for a small side project or a curious quick check, so this is how I do it. The same syntax works for both Google and Bing.

Read more…

Oh Shit, Git!?!

Notes | 2025-07-02 (updated 2025-10-25) | 1 min read
#git

Git is hard: screwing up is easy, and figuring out how to fix your mistakes is fucking impossible. Git documentation has this chicken and egg problem where you can’t search for how to get yourself out of a mess, unless you already know the name of the thing you need to know about in order to fix your problem.

Oh Shit, Git!?! is a collection of these situations, in plain English, and how to resolve them.

Caddy: Custom Domains for SaaS

Notes | 2025-07-02 (updated 2025-10-25) | 2 min read
#caddy

Building custom domains for your SaaS is not always easy, especially when certificates get involved.

With Caddy it becomes very easy!

Read more…

Guest Appearance: Nginx Community Chats

Posts | 2025-06-12 (updated 2025-10-24) | 1 min read
#guest-apperance #nginx

I had the pleasure of joining Dave McAllister, Senior Open Source Technologist for NGINX, on the NGINX Community Chats to talk about tech playground.

Read more…

Colorize pattern on CLI

Notes | 2025-05-07 (updated 2025-10-25) | 1 min read
#bash #grep #productivity

Colorize a pattern in the given input using a neat regex and colorization hack in grep ($ matching all lines but not being able to be highlighted).

color () {
  # Color highlight the pattern in the incoming stream, writing to stdout
  # This effectively matches our PATTERN andy any "$" (line end)
  # But only our PATTERN can be highlighted, line end characters aren't actually there to be highlighted
  local PATTERN=$1

  if [ -z "$1" ]; then
    echo "Usage: color <pattern>"
    echo "Description: Greps input with --color=always -E 'PATTERN|\$' "
    echo "Example: echo \"hello world\" | color \"world\""
    return 1

  fi
  grep --color=always "$PATTERN\|\$"
}

kubeswitch: The kubectl for operators

Notes | 2025-04-17 (updated 2025-10-25) | 1 min read
#k8s #tools

kubeswitch (lazy: switch) is the single pane of glass for all of your kubeconfig files. Caters to operators of large scale Kubernetes installations. Designed as a drop-in replacement for kubectx.

I’m using it for all my cluster-switching needs.

pip install from git repository

Notes | 2025-04-14 (updated 2025-10-25) | 1 min read
#git #pip #python

Install a pip package from a git repo, using a specified git reference:

Read more…

DrawKit

Notes | 2025-04-13 (updated 2025-10-25) | 1 min read
#tools

Hand-drawn 2D & 3D illustrations, icons and animations.

Incredibly high quality illustrations.

I use them in a bunch of places, especially on landing pages and in presentations that just need that little “extra” thing.

Troubleshooting Intermittent DNS Resolution Issues

Notes | 2025-02-28 (updated 2025-10-25) | 1 min read
#bash #dns #troubleshooting

DNS is something so fundamental to most of our systems functioning that it’s often overlooked in initial troubleshooting, it’s also incredibly hard to troubleshoot if it’s only intermittently failing.

Read more…

GitLab Copy & Paste: Added Backticks

Notes | 2025-02-26 (updated 2025-10-25) | 1 min read
#gitlab

Read more…

Running Multiple Server Processes From One Script

Notes | 2025-02-23 (updated 2025-10-25) | 1 min read
#bash #microservices #scripting

Doing local development on a bunch of interconnected services I often want to start multiple long running server processes.

This is the basic script I use for that.

Read more…

kubectx & kubens

Notes | 2025-02-17 (updated 2025-10-25) | 1 min read
#k8s #tools

When working with multiple Kubernetes clusters and namespaces switching context can be a chore.

For this I enjoy using kubectx and kubens.

They can be installed using kubectl krew.

kubectl krew install ctx
kubectl krew install ns
I’ve since switched to [[kubeswitch]], which works much nicer for me.

Simple Redirect View for Django

Notes | 2025-01-02 (updated 2025-10-25) | 1 min read
#django #python

I often find myself replacing an existing MVP based on static html with a Django app, or just needing to preserve some old URL scheme.

This is the code I use to do that:

from django.shortcuts import redirect

def redirect_view(request, redirectable, permanent=True):
  return redirect(redirectable)

Which can then be used like this:

from django.urls import path
from . import views

urlpatterns = [
    path("old-url/", views.redirect_view, {"redirectable": "new_view"}),
    path("some-thing/", views.redirect_view, {"redirectable": "some_thing_new", permanent=False}),
]

Cleanup After Script Exit

Notes | 2024-09-03 (updated 2025-10-25) | 1 min read
#bash #linux #scripting

Many of my scripts work with temporary files, usually relative to the scripts directory1, while at the same time using set -e to exit as soon as something fails.

In this scenario the script leaves behind these temporary files by default, which is not desirable.

We can however do a proper cleanup using the trap concept.

Read more…

iperf Cheatsheet

Notes | 2024-07-30 (updated 2025-10-25) | 1 min read
#cheatsheet #iperf

Read more…

Vault CLI in Containers

Notes | 2024-07-25 (updated 2025-10-25) | 2 min read
#cicd #container #devops #hashicorp-vault

In many CI/CD workflows interfacing with Hashicorp Vault is required.

However, their CLI (or better called unified binary1) is stupidly big with more than 400MB and they seem to have no interest in making it any smaller2.

This is often a undesired size increase, especially when optimizing for pull and run time in CI/CD.

This note outlines a solution that brings us down from 400MB+ on disk for vault to about 300KB using curl and jq.

Read more…

Caddy: Manual Maintenance Mode

Notes | 2024-07-13 (updated 2025-10-27) | 2 min read
#caddy #sysadmin

Coming from NGINX and others the concept of a maintenance mode that can be manually enabled is something I have used many times before.

With Caddy it is equally as easy, just using a less obvious syntax.

Read more…

Caddy

Notes | 2024-07-13 (updated 2025-10-25) | 0 min read
#caddy #slashpage-uses

Find files and folders with spaces

Notes | 2024-06-27 (updated 2025-10-25) | 1 min read
#bash #find #powershell

On Linux/Unix/MacOS:

find . | grep " "

On Windows:

Get-ChildItem -Path "." -Recurse -Filter "* *" | Format-Table FullName

PicoCSS Sticky Footer

Notes | 2024-06-10 (updated 2025-10-25) | 1 min read
#picocss

A sticky footer using [[picocss]]

html,
body {
  height: 100vh;
}

body > footer {
  position: sticky;
  top: 100vh;
}

Renovate Bot: Limit Manager To Folder (Ignore Paths)

Notes | 2024-06-04 (updated 2025-10-25) | 2 min read
#renovate-bot

When using Renovate it can sometimes be required to run a specific manager only on a sub-set of the matching files.

Naively you might expect this to be achieved by overwriting the fileMatch property of the manager. However this is not possible, as this property gets merged together, effectively meaning we can only append to it, not replace it.

What I found working is an approach using either includePaths or ignorePaths, depending on the situation.

Read more…

HaProxy: Think About DNS Resolution

Notes | 2024-06-04 (updated 2025-10-25) | 1 min read
#haproxy #linux #sysadmin

By default HAProxy resolves all DNS names in it’s config on startup and then never again.

This might cause issues down the road if DNS records, for example the ones for backends, change.

This section of the documentation is a good starting point as it describes IP address resolution using DNS in HAProy really well: https://docs.haproxy.org/3.0/configuration.html#5.3

Additionally this guide can also be helpful: https://www.haproxy.com/documentation/haproxy-configuration-tutorials/dns-resolution/

sed: Delimiter Issues

Notes | 2024-05-16 (updated 2025-10-27) | 1 min read
#sed

When doing variable substitution with sed things break if the value contains the delimiter used by sed.

Read more…

JQ Cheatsheet

Notes | 2024-05-16 (updated 2025-10-26) | 2 min read
#cheatsheet #jq

Read more…

Interactive Containers Cheatsheet

Notes | 2024-04-29 (updated 2025-10-25) | 1 min read
#cheatsheet #container #docker #podman

Most of these should work the same with any OCI compliant client. Tested with podman and docker, unless otherwise indicated.

# Run container interactively
podman run -it IMAGE:TAG SHELL

# With auto removing the container on exit
podman run -it --rm IMAGE:TAG SHELL

# With current working dir mounted to container
podman run -it -v ${PWD}:/tmp/host-dir/ IMAGE:TAG SHELL

# Detaching from the interactive session
# Keybinding: Ctrl+P, then Ctrl+Q

# Attaching to a container
podman attach "ID OR NAME"

Windows 11: Taskbar

Notes | 2024-03-12 (updated 2025-10-25) | 1 min read
#windows

For some reason Microsoft, in their infinite wisdom, decided to no longer support moving the taskbar to other edges of the screen with Windows 11.

Using a utility like ExplorerPatcher the whole task bar can be reverted to something close to Windows 10, including moving it to all screen edges.

Bash: Find All Folders Containing File With Name

Notes | 2024-03-01 (updated 2025-10-25) | 1 min read
#bash #scripting

fileName="my-file.yaml"
find . -type f -name "$fileName" -printf "%h\n"

Working With Dates in Bash and Other Shells

Notes | 2024-02-22 (updated 2025-10-25) | 1 min read
#bash #linux #scripting

Often times we need the current date (and time) when scripting inside bash or other shells. For example when creating a backup file or writing to a log.

Read more…

Managing Multiple Kube Config Files

Notes | 2024-02-22 (updated 2025-10-25) | 1 min read
#k8s #productivity #scripting

This is a simple script that takes multiple kube config files and deeply merges them into one.

I’ve since switched to [[kubeswitch]], which works much cleaner than this home-grown script.

Read more…

Wait for Port to Close Using Ansible

Notes | 2024-02-20 (updated 2025-10-25) | 1 min read
#ansible

Sometimes it is useful to wait for a port to be closed, for example when updating an app that can’t always properly be shut down using other Ansible modules.

This can easily be achieved using the ansible.builtin.wait_for or ansible.builtin.win_wait_for module.

Read more…

PicoCSS

Notes | 2024-02-10 (updated 2025-10-25) | 1 min read
#picocss #slashpage-uses

My preferred minimalistic CSS framework, which is usually enough for small websites and even simple SaaS apps. It feels like a super power to write almost plain HTML and get something that looks presentable, supports dark mode and has just enough components to cover most use cases for me.

Navigate to Script Directory

Notes | 2024-01-28 (updated 2025-10-25) | 1 min read
#bash #linux #scripting

Often times when writing scripts I want to reference files in the same directory, but keep the script portable in case it is part of a git repository being checked out somewhere else or just the folder getting moved.

Read more…

Show Size of Elements Using JavaScript

Notes | 2024-01-19 (updated 2025-10-25) | 1 min read
#debugging #javascript

I was recently doing a lot of layouting pages to later be printed, so showing how big certain elements are was of help to me.

This is a JavaScript function that does just that.

Read more…

My First Show Hacker News

Experiences & Statistics

Posts | 2024-01-19 (updated 2025-10-22) | 3 min read
#indie-hacking #products #writeup

A while back I built tech-playground.com, which I describe like this:

A playground that runs your config on real servers for you, a bit like CodePen for server tech.

Read more…

Spread Elements Vertically Using CSS

Notes | 2024-01-18 (updated 2025-10-25) | 1 min read
#css

Using flex children can easily be positioned vertically in their parent container.

Read more…

Debugging CSS Layouts

Notes | 2024-01-17 (updated 2025-10-25) | 1 min read
#css #debugging

When debugging issues with CSS layouts it can sometimes be tricky to really understand what is going on.

Read more…

Simple Copy Button Using JavaScript

Notes | 2024-01-16 (updated 2025-10-25) | 1 min read
#javascript

I often find myself wanting a simple copy button in my web projects.

This is the recipe I build them from using clipboard.js and a couple lines of JavaScript.

Read more…

Generate link in plain text element using JavaScript

Notes | 2023-12-17 (updated 2025-10-25) | 1 min read
#javascript

Sometimes, when working with externally generated content you might want to make links clickable when rendering it in the client.

This is a snippet to do just that.

Read more…

Debugging Container Workloads

A Helper Container

Posts | 2023-12-04 (updated 2025-10-23) | 1 min read
#containers #debugging #k8s #python

Debugging container workloads can be a challenge sometimes, especially when running them in k8s, behind a reverse proxy or in other, possibly complex, traffic flow scenarios.

Read more…

Register all models with Django admin

Notes | 2023-11-16 (updated 2025-10-25) | 1 min read
#django #python

Sometimes, mostly when throwing together a quick idea or MVP, it can be useful to just register all models with the admin and leave proper customization for later.

Read more…

Add fields to list with Kustomize

Notes | 2023-10-18 (updated 2025-10-25) | 1 min read
#k8s #kustomize

How to add things to a list using kustomize. This is useful for example when you need to patch additional environment variables into a pod.

Read more…

CLI fuzzy search

Notes | 2023-10-08 (updated 2025-10-25) | 1 min read
#linux #productivity #search #slashpage-uses

I often whish to search through large bodies of text, like my knowledge base or source code repositories, from the command line.

I use fuz for this and I’m quite happy with it.

I also have it aliased to my knowledge base folder for even easier searching.

alias search="fuz -p /path/to/knowledge-base/"

Render Plain HTML with Hugo

Notes | 2023-10-07 (updated 2025-10-25) | 1 min read
#hugo

Hugo is my favorite tool for publishing markdown to the internet, but sometimes I want to do something a little bit more advanced with my posts.

With this shortcode I can always just fall back to plain old HTML.

Read more…

Copy & Paste Is Dangerous

Posts | 2023-10-07 (updated 2025-10-22) | 2 min read
#bash #security #writeup

Copy & paste from untrusted sources on the internet into the terminal is a really bad idea! Early in my career I did it too and still often see others doing it.

Read more…

Hugo Details Shortcode

Notes | 2023-10-06 (updated 2025-10-25) | 1 min read
#hugo

The HTML details element is a nice way to create natively expandable content with wide browser support.

Read more…