RSSAmplifier

Blog

marco.ninja - Blog Feed

Latest posts and notes from marco.ninja

marco.ninjaRSS feed ↗142 posts

Latest posts

Excalidraw Figures in Hugo

I love drawing things, especially in Excalidraw! I also need more dark mode support in my life. In this post I’ll go through how I made Excalidraw exports render nicely on my blog in a light or dark mode aware fashion.

Introducing snippethost.gitlab.io

It is no secret that I’m no big fan of GitHub and it’s dominance in the VCS-ecosystem. So in an effort of leveling the playing field I’m taking it onto myself to build more cool things for and with my VCS of choice, GitLab!

Devlog 2026-01-04

Over the holidays I’ve been diving deep into build systems in general and container builds in particular.

Static Site Generator Fulltext Search

I recently rebuilt my blog from scratch, see the previous post in this series . One thing I wanted to add was site-wide search without any external dependencies. Since I have previous experience with a tool called pagefind , which is perfect for this use case, I implemented it with that.

Remaking My Blog From Scratch

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.

Hugo Environment Variable Magic

You can overwrite hugo configuration values with environment variables!

Finding PID Everywhere

Usually at least one of those is present on any system top htop / another top variant ps 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…

Hacking Comments Into 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…

Replace item in list with 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.

Easy Backlink Check

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.

Caddy: Custom Domains for SaaS

Building custom domains for your SaaS is not always easy, especially when certificates get involved. With Caddy it becomes very easy!

Oh Shit, 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…

Guest Appearance: Nginx Community Chats

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

Colorize pattern on CLI

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…

kubeswitch: The kubectl for operators

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

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

DrawKit

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

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.

GitLab Copy & Paste: Added Backticks

Running Multiple Server Processes From One Script

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.

kubectx & kubens

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

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…

Cleanup After Script Exit

Many of my scripts work with temporary files, usually relative to the scripts directory 1 , 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.

iperf Cheatsheet

Vault CLI in Containers

In many CI/CD workflows interfacing with Hashicorp Vault is required. However, their CLI (or better called unified binary 1 ) is stupidly big with more than 400MB and they seem to have no interest in making it any smaller 2 . 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…

Caddy

Caddy: Manual Maintenance Mode

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.

Find files and folders with spaces

On Linux/Unix/MacOS: find . | grep ' ' On Windows: Get-ChildItem -Path '.' -Recurse -Filter '* *' | Format-Table FullName

PicoCSS Sticky Footer

A sticky footer using [[picocss]] html , body { height : 100 vh ; } body > footer { position : sticky ; top : 100 vh ; }

HaProxy: Think About DNS Resolution

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…

Renovate Bot: Limit Manager To Folder (Ignore Paths)

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…

JQ Cheatsheet

sed: Delimiter Issues

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

Interactive Containers Cheatsheet

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…

Windows 11: Taskbar

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

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

Managing Multiple Kube Config Files

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.

Working With Dates in Bash and Other Shells

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.

Wait for Port to Close Using 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.

PicoCSS

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

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.

My First Show Hacker News

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.

Show Size of Elements Using 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.

Spread Elements Vertically Using CSS

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

Debugging CSS Layouts

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

Simple Copy Button Using 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.

Generate link in plain text element using 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.

Debugging Container Workloads

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.

Register all models with Django admin

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.

Add fields to list with 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.