Standing up GitLab EE on DigitalOcean: the gotchas I'd avoid next time — — Built a fresh GitLab EE 18.11 lab on DO droplets — Ultimate-NFR license, top-level group, owner-access user accounts, 9 docker-executor runners. Worked, eventually. A dozen pitfalls along the way turned a one-hour task into four hours. Writing them down so the next build is forty-five minutes.
UpNote (and any Electron app) won't show a window on NVIDIA + Wayland — — Installed UpNote on Ubuntu 26.04 with an NVIDIA card. Process runs, tray icon registers, no window ever appears. Two stacked failures: the Chromium GPU process segfaults on the nvidia-drm node, and Electron's native Wayland backend silently fails to map the toplevel. Fix: --disable-gpu --ozone-platform=x11 in the .desktop launcher.
The '?' on the WiFi icon that won't go away across Ubuntu 24, 25, 26 — — Three Ubuntu releases in a row, the WiFi indicator paints a question mark while the network works fine. It's NetworkManager's connectivity check failing against the default Ubuntu endpoint. Pointing it at GNOME's has fixed it for me on every release.
Cutting musicmod's CI from 12 minutes to 2 — — musicmod's release builds were burning ~12 minutes apiece — long enough that a busy day of tagging blew through the GitHub Actions Pro budget twice. Three changes (a dropped matrix entry, a registry-backed Docker cache, and a .dockerignore) took every subsequent build down to about 1m50s.
WireGuard import is still broken in Ubuntu 26.04 — — The GUI VPN importer silently drops the [Peer] section on WireGuard configs. The connection appears, activates, and does absolutely nothing. Here's the nmcli workaround that actually works — and why the GUI is still where I want to live.
Making nginx more resilient: runtime DNS resolution and auto-restart — — An internal site silently disappeared for three days after nginx failed a reload because DNS was briefly unavailable. Two tiny config changes — runtime upstream resolution and a systemd Restart drop-in — make that failure mode impossible.
Adding HA to a single-container SQLite web app, without moving to Postgres — — Three options for SQLite HA. The first is overkill. The second is the obvious answer that didn't work — we burned ~600 lines of glue trying to make Litestream and an embedded SFTP server cooperate. The third is 80 lines of Python that POSTs the DB over HTTPS every thirty seconds. Guess which one we shipped.
Why my duplicate-detection was 100× slower than it should have been — — Audio fingerprints aren't hashes. They're short time-series, and comparing them in pure Python means paying the interpreter tax on every single sample. Here's the cliff I walked off, and the one-line numpy fix.
Home, office, and a bastion in the cloud — one WireGuard config — — Neither my home nor my office has a public IP. I still wanted every device I own to reach both LANs as if it were sitting in either building. A small cloud bastion and one well-crafted WireGuard config solved it.
Running GitLab MCP from my couch (via Cloudflare Tunnel) — — I wanted Claude to open MRs and triage issues in my self-hosted GitLab from my phone. Claude web runs on Anthropic's infrastructure, not my LAN — which meant rethinking how the MCP connects.
acme.sh quietly runs my entire lab's TLS — — Certbot is fine. But if you're issuing certs across a home lab — wildcards, multiple CAs, weird DNS providers — acme.sh is the tool I keep coming back to. One shell script, zero plugin installs, a wildcard cert in about fifteen seconds.
How awkto.dev ships itself — — From a Lovable-generated Vite app to a fully wired awkto.dev — Cloudflare Workers, GitHub Actions, a dev preview branch, a new domain and two-way email, without standing up a single server.