Archives
All the articles I've archived.
-
Self-Hosted Runner Investigation: Resource Usage, BuildKit Cache Bloat, and Shared Registry Plan
Deep-dive into actual resource consumption of Multipass GitHub Actions runners — uncovering 85GB of BuildKit cache waste per runner, and a plan to replace it with a shared Docker registry cache.
-
Open Source Server Monitoring: Resources, Services, Dashboards, and Alerts
A practical overview of self-hosted monitoring solutions for server resources and running services — covering tools, common practices, and alerting strategies.
-
Dependencies, Healthchecks, and Startup Order in Compose
depends_on with conditions, service_healthy, and the traps around startup ordering — because 'started' doesn't mean 'ready'.
-
Compose Profiles and Environment Management
Profiles for optional services, .env files for configuration, multiple compose files for overrides — managing complexity in Docker Compose without duplicating everything.
-
Compose Watch and Hot Reload for Development
docker compose watch for automatic sync and rebuild — replacing bind mount hacks with a first-class development workflow.
-
Debugging Running Containers
exec, logs, inspect, cp, attach — the toolkit for understanding what's happening inside a container without rebuilding it.
-
Docker Compose from Scratch
Services, networks, volumes, and the compose file structure — the basics of multi-container applications done right from day one.
-
Docker Build Cache: What Invalidates It and How to Fix It
Layer caching, BuildKit cache mounts, and registry-based caching — understanding what makes builds slow and how to make them fast again.
-
Healthchecks: Letting Docker Know Your App Is Actually Running
The HEALTHCHECK instruction, health states, and how proper healthchecks change restart behavior and service dependency ordering.
-
Docker Init: Scaffolding Dockerfiles for Your Stack
docker init generates Dockerfiles, compose files, and .dockerignore for your project — when it saves time and when you should write your own.
-
Writing Dockerfiles That Don't Fight You
FROM, COPY, RUN ordering, layer caching, .dockerignore — the decisions that determine whether your builds are fast and predictable or slow and surprising.
-
Docker Mastery: A Practical Guide from Zero to Production
A curated series of Docker articles progressing from fundamentals through Compose to single-server production — each covering one topic in depth with commands, patterns, and gotchas.
-
Monitoring Containers: Stats, Events, and Knowing What's Wrong
docker stats, container events, cAdvisor, and lightweight monitoring stacks — from quick CLI checks to proper dashboards.
-
Multi-Stage Builds: Smaller Images, Cleaner Separation
How multi-stage Docker builds separate build-time dependencies from runtime, producing smaller and more secure images without complex scripting.
-
Understanding Docker Networking
Bridge, host, and custom networks — how containers find each other, when port mapping matters, and how to stop using IP addresses for everything.
-
Docker Networking in Production
Reverse proxies with Traefik and Caddy, TLS termination, internal vs external networks — the networking patterns that take Docker from development to production.
-
Docker Logging: Drivers, Rotation, and Not Filling Your Disk
Log drivers, json-file rotation limits, journald integration, and centralized logging — because unlimited container logs will eventually eat your disk.
-
Resource Limits: CPU, Memory, and Why Defaults Are Dangerous
How to set memory and CPU limits on Docker containers, what happens when they're exceeded, and why running without limits is a production risk.
-
Restart Policies and Process Supervision
restart: unless-stopped vs always, systemd integration, and keeping containers alive without an orchestrator.
-
What Happens When You Run docker run
The mental model behind Docker images, containers, and layers — what actually happens from command to running process, and why understanding the lifecycle matters for everything else.
-
Basic Security Hardening for Docker
Non-root users, read-only filesystems, dropped capabilities, and secrets management — the baseline security measures every Docker deployment should have.
-
Tagging and Pushing Images Without the Mess
Tag strategies, registry basics, and multi-arch builds — shipping Docker images with a system instead of ad-hoc names.
-
Docker Volumes and Bind Mounts
Named volumes, bind mounts, and tmpfs — how Docker handles persistence, when to use each, and the permission problems that catch everyone.
-
DuckDB: The Embedded Analytical Database
Research into DuckDB — what it is, how it compares to SQLite, ClickHouse, and Polars, and when to use it for local data analysis.
-
Choosing a Container Orchestrator: A Decision Framework
Docker Swarm, Kubernetes, k3s, Nomad, ECS, Cloud Run, Fly.io — when each makes sense, a decision matrix by team size and workload, and the business cases where each wins.
-
Docker Swarm: Built-In Orchestration Without the Complexity
Docker Swarm mode turns a group of Docker hosts into a cluster with built-in service discovery, load balancing, and rolling updates — using the Docker CLI you already know.
-
AWS ECS and Fargate: Managed Containers Without Kubernetes
Amazon's container orchestration service — EC2 launch type for control, Fargate for serverless containers, and when to choose ECS over EKS.
-
Container Orchestration: A Practical Guide to Every Major Option
Docker Swarm, Kubernetes, k3s, Nomad, ECS, Cloud Run, Fly.io — what each does, how to set it up, and when it's the right choice for your team and workload.
-
k3s: Lightweight Kubernetes for the Real World
A single binary, production-ready Kubernetes distribution — from single-node development to multi-node edge clusters, without the operational weight of full K8s.
-
Kubernetes Fundamentals: The Mental Model
Pods, Services, Deployments, and the control loop — understanding Kubernetes architecture and core concepts before touching kubectl.
-
Google Cloud Run and Azure Container Apps: Serverless Containers
Run containers without managing infrastructure — Cloud Run and Azure Container Apps handle scaling, TLS, and billing per request.
-
Fly.io, Railway, and Modern Container PaaS
Deploy-focused platforms that run Docker containers globally — push your code, get a URL, skip the infrastructure.
-
HashiCorp Nomad: The Orchestrator That Isn't Only for Containers
A simpler alternative to Kubernetes that schedules containers, VMs, Java apps, and batch jobs — with a single binary, no PhD required.
-
Sentry: Error Monitoring and Performance Tracking
An overview of Sentry, the developer-first error tracking and performance monitoring platform — how it works, what it captures, and how to set it up.
-
Umami: Privacy-Focused Web Analytics
An overview of Umami, the open-source, self-hosted analytics platform that serves as a privacy-respecting alternative to Google Analytics.
-
Home Server Series: From Desktop to Self-Hosted Infrastructure
A complete guide to converting a desktop machine into a home server running K3s, media services, photo backup, custom web apps, and monitoring — organised as a series of focused articles.
-
Home Server Part 1: Market Research — What's Out There
Surveying the 2025-2026 landscape for home server setups: Linux distros, container orchestration, media automation, photo backup, reverse proxies, auth layers, remote access, and monitoring.
-
Home Server Part 2: Requirements and Decisions — Why We Chose This Stack
Narrowing down from market research to concrete choices: Ubuntu over Proxmox, K3s over Docker Compose, CronJobs over Knative, Jellyfin over Plex, and the honest take on serverless at home.
-
Home Server Part 3: Cluster Setup — Ubuntu Server, K3s, and Traefik
Installing Ubuntu Server 24.04 with LVM, K3s single-node Kubernetes, storage classes, and Traefik ingress with host-based routing and dashboard.
-
Home Server Part 5: Monitoring — Grafana and Prometheus
Deploying the kube-prometheus-stack on K3s via Helm, configuring Grafana dashboards for cluster and system monitoring, and recommended pre-built dashboards.
-
Home Server Part 6: Photos — Immich as a Google Photos Replacement
Deploying Immich on K3s via Helm chart with persistent storage, Traefik ingress, and mobile auto-backup configuration.
-
Home Server Part 7: Media Server — Jellyfin for Video Streaming
Deploying Jellyfin on K3s with shared persistent storage, Traefik ingress, and how it connects to the torrent service for seamless media access.
-
Home Server Part 8: Torrent Service — qBittorrent with VPN Protection
Deploying qBittorrent with Gluetun VPN sidecar on K3s, Mullvad configuration, shared volumes with Jellyfin, and the web UI download workflow.
-
Home Server Part 9: Legal Situation — Torrenting in Sweden
The current legal landscape for torrenting in Sweden: copyright law, IPRED enforcement, settlement letters, ISP behaviour, and why download-only is a myth.
-
Home Server Part 4: App Hosting — APIs, Frontends, and Databases on K3s
The repeatable pattern for hosting your own projects on K3s: namespace-per-app, PostgreSQL/MongoDB, Go/Node/Rust APIs, static frontends, Traefik routing, image builds, deploy scripts, and CronJob scheduling.
-
Claude Mythos Preview: AI-Driven Zero-Day Discovery at Scale
Abstract of Anthropic's red-team report on Claude Mythos Preview's unprecedented ability to find and exploit zero-day vulnerabilities across major open-source software.
-
Cleaning Up Build Artifacts and Caches with git clean
How to use git clean to remove untracked files, build output, and caches from your working tree — with dry runs, exclusion patterns, and the flags that control what actually gets deleted.
-
Questions to Discuss with Your Partner Before Baby Arrives
A structured list of questions to help couples align on parenting, finances, responsibilities, and boundaries before the baby comes.
-
The Great Reorg: It's Not About Replacing People
Foundation Capital's research on how companies are reorganizing around AI — and why the real risk isn't job loss but breaking the junior talent pipeline.
-
Per-File Git Behavior with .gitattributes
How .gitattributes controls merge strategies, diff output, line endings, and export behavior on a per-file or per-pattern basis — solving whole categories of recurring git friction.
-
Finding When Code Appeared or Disappeared with Git Pickaxe
How to use git log -S and -G to trace exactly when a string or pattern was added, removed, or changed across the entire history of a repository.
-
Comparing Patch Series with git range-diff
How to use git range-diff to see what actually changed between two versions of a branch — before and after a rebase, or between PR iterations.
-
Attaching Metadata to Commits with git notes
How git notes let you annotate commits with additional context — deployment timestamps, review feedback, CI results — without altering commit SHAs or rewriting history.
-
Finding Regressions Automatically with git bisect
How git bisect uses binary search to identify the exact commit that introduced a bug — and how to fully automate the process with git bisect run.
-
Exporting Clean Snapshots with git archive
How git archive creates tarballs and zip files from any commit, tag, or branch — without the .git directory and with fine-grained control over what gets included.
-
Transporting Git Repositories Offline with git bundle
How to package a git repository or a range of commits into a single portable file — for air-gapped transfers, offline backups, or sharing history without network access.
-
Git Blame Beyond the Basics
The flags that make git blame genuinely useful: line ranges, copy detection across files, whitespace-aware attribution, and output formatting for scripts.
-
Hiding Formatting Commits from Git Blame with .git-blame-ignore-revs
How to use .git-blame-ignore-revs to stop formatting-only commits from polluting git blame, preserving the ability to trace actual logic changes back to their authors.
-
Rewriting History Precisely with git rebase -i and --onto
How interactive rebase gives you surgical control over commit history, and how --onto lets you transplant a branch segment onto any base.
-
Git Aliases That Go Beyond Shortcuts
How git config aliases can run shell commands, accept arguments, chain multiple operations, and become first-class workflow tools — not just abbreviations.
-
Git Stash Beyond the Basics
Named stashes, partial stashing, applying without dropping, creating branches from stashes, and understanding what git stash actually stores.
-
Never Resolve the Same Conflict Twice with git rerere
How git rerere records conflict resolutions and automatically replays them — essential for long-running branches that regularly merge or rebase against a changing base.
-
Checking Out Only What You Need with git sparse-checkout
How to use git sparse-checkout to work with a subset of a large repository — checking out only specific directories without downloading or materializing the rest.
-
Embedding Repositories with git subtree
How git subtree lets you include and sync another repository as a subdirectory — without .gitmodules, detached HEADs, or recursive clone flags.
-
Git Tags Done Right: Lightweight, Annotated, and Signed
The difference between lightweight and annotated tags, when to use each, how signing works, and the full workflow for managing release tags in a team repository.
-
Git Features Worth Knowing: A Practical Index
A curated map of underused git features grouped by the situations where they matter most — debugging regressions, reviewing code, managing history, handling large repos, and shipping releases.
-
SST for Preview Environments and CI/CD in Solo Development
How SST's stage model enables per-PR preview environments and automated deployments, with practical GitHub Actions patterns and cost analysis for a solo developer.
-
Go & Rust for Cost-Effective Serverless: What the Data Actually Shows
A research-driven look at how engineers are using Go and Rust to build high-performance, low-cost serverless web services on AWS, Cloudflare, and GCP.
-
Go for TypeScript Developers: A Practical First Steps Guide
Core Go syntax, project setup, and mental model shifts for developers coming from the TypeScript/Node.js world.
-
Getting the Most Out of OpenCode CLI
Deep dive into OpenCode's plugin ecosystem, token optimization tools (RTK equivalents), task planning workflows, and configuration strategies for a solo developer.
-
Rust for TypeScript Developers: A Practical First Steps Guide
Core Rust syntax, ownership model, project setup, and mental model shifts for developers coming from the TypeScript/Node.js world.
-
Terminal Migration: Alacritty Alternatives for macOS + Arch + Zellij + Neovim
Investigating terminal emulator options to replace Alacritty, focusing on macOS full-screen stability with external monitors, cross-platform consistency, and Zellij/Neovim compatibility.
-
Choosing a Static Site Generator for a Markdown Knowledge Base
A comparison of static site generators for publishing markdown notes as a structured blog, covering Quartz, Astro/AstroPaper, and Hugo/PaperMod, with notes on search, tags, S3 deployment, and managing draft versus published content.
-
AI Brain Fry: Cognitive Overload from AI Tool Usage
A summary of a March 2026 HBR study on acute cognitive fatigue caused by AI tool oversight, covering key data points, the productivity paradox, and what organisations can do to mitigate it.
-
Off-Main-Thread Architecture: Web Workers for Frontend Decoupling
An investigation into using Web Workers with an event-driven message bus to decouple data fetching from React and Svelte render lifecycles, covering transport mechanisms, request deduplication, and practical trade-offs against existing solutions like TanStack Query.
-
Free Tunneling Solutions for Docker Compose Preview Environments
A comparison of free tunneling options for exposing Docker Compose applications to external reviewers without router configuration, covering Cloudflare Tunnel, ngrok, localhost.run, and Tailscale.
-
Self-Hosting Observability: Loki, Grafana, and Gatus vs Managed SaaS
An investigation into self-hosted observability alternatives for production Kubernetes applications, comparing a Loki + Grafana + Gatus stack against AWS-native services and managed SaaS, with cost analysis and a phased implementation plan.
-
Telegram Bot API: States, Command Scoping, and UI Features
A reference overview of Telegram Bot API capabilities covering state management patterns across frameworks, command visibility scoping, keyboard types, Mini Apps, and persistent UI elements like pinned messages.
-
Task Management Workflows for AI Coding Assistants
A survey of approaches for structuring task intake and autonomous execution with AI coding assistants, from native tools to GitHub Issues integration, MCP servers, and enterprise orchestration platforms.
-
Integrating Cucumber BDD with Playwright for End-to-End Testing
An investigation into combining Cucumber's Gherkin syntax with Playwright for browser automation, covering setup approaches, step reuse patterns, and when the integration is the right choice.
-
Tailwind CSS: Implementing Complex Multi-Layered Gradients
A brief investigation into the right approach for complex radial gradients with aspect-ratio media queries in Tailwind CSS, and why @layer utilities is the recommended escape hatch.
-
Git Worktrees: Multiple Working Directories for a Single Repository
A technical overview of git worktrees — how they work, when to use them, process isolation considerations, and practical management for developers who frequently switch context between branches.
-
React useMemo for Array Slices: When It Helps and When It Doesn't
A technical analysis of whether Array.slice() operations in React components warrant useMemo optimisation, with performance benchmarks, practical decision criteria, and common anti-patterns to avoid.
-
Development Team Dashboards: Metric Selection, TV Layout, and Implementation
An exploration of what makes a sprint health dashboard useful rather than anxiety-inducing, covering metric selection principles, TV display layout design, and a lightweight technical implementation approach using the GitHub API.
-
Git Workflow: Merge vs Rebase for Feature Branches
A practical comparison of git merge vs rebase for keeping feature branches in sync with main, and why rebase leads to cleaner PRs and better code reviews.