security The CodeQL Alert: Shell Command Built From Environment Values Alert #178 flagged a cleanup script that built a shell string from process.env.DB_PASSWORD. The fix isn't escaping the value — it's not building a shell string at all.
cel Server-Side CEL Type-Checking as a CI Lint kubectl --dry-run=client accepts a ValidatingAdmissionPolicy with a broken CEL expression. --dry-run=server compiles it, names the column of the error, and exits 1 — with nothing persisted. That is a free CI lint.
security What a Year of CodeQL Alerts Looks Like on a Solo Project Eight code-scanning alerts, four distinct classes, fixed one at a time across a year of commits — the real pattern is that rate limiting had to be fixed six separate times before it stuck.
containers 105 CVEs to Zero in 40 Seconds: What Copacetic Actually Does to an Image Copacetic patched every fixable OS CVE on our fixtures without a rebuild — and left every application dependency untouched. Both halves of that sentence matter.
fishing-tracker-pro Recommending the Best Time to Fish: Weather, Tide, and Solunar Theory The Plan Trip tab combines a real weather/tide forecast with solunar fish-activity theory to recommend a time window — and the fishing-method filter bug that shipped before the useful version did.
backend Scraping a Government Weather Site Because There's No API Mauritius Meteorological Services publishes accurate sunrise, sunset, moonrise, and moonset tables on a public website — with no API. Here's the scraper, the cache, and the fallback.
architecture Three Data Sources, One Feature: Moon, Tide, Weather Per Trip One enrichment step, three upstream sources with three different failure modes — a local lunar calculation, a tide API, and a weather API layered over a government-site scrape.
product A Fishing Log That Knows the Tide Fishing Tracker Pro doesn't just record what you caught — every trip is stamped with the moon phase, tide state, and weather at the moment you logged it.
kubernetes Public Project or Nothing: The Proxy-Cache Setting That Is Not a Preference The kubelet pulls with no imagePullSecrets at all — 32 of 32 pods pull from harbor/dockerhub and it works only because the project is Public. Copying the 'apps' project's Private setting took two workloads down.
dns Auditing Your Own Infra and Finding the Thing You Forgot traefik.nissaar.com is referenced by name in the dashboard's own router labels and has never resolved to anything — no incident surfaced it, no alert fired, and it was only found by deliberately cross-checking labels against DNS.
vap Phase In a Binding, Not a Policy With native VAP, the grace period lives in the binding's validationActions, never in the policy object. The same four violating Pods still report as failures under [Warn, Audit] — but the run exits 0, and phase 3 is opt-in by namespace label.
docker Why the Infra Repo Should Never Contain Your Data nextcloud/, nextcloud_data/, db/, and redis/ are bind-mounted directories that live entirely on vmi2633427, are gitignored on purpose, and are explicitly not backed up by the repo that describes the stack running on top of them.
vap Native ValidatingAdmissionPolicy vs Kyverno, Same Two Controls The registry allow-list and the digest-pinning control were reimplemented as native CEL ValidatingAdmissionPolicies and run against the identical fixtures. Same verdict on every Pod — and CEL's messageExpression names the offending image.
git A Deploy Key That Can Only Pull root on vmi2633427 has no GitHub identity of its own, and the deploy only ever needs to pull — so the key it authenticates with is generated, scoped, and verified to be read-only before it ever touches the server.
containers Build the Fixtures Before the Tools: A Testing Methodology for Container Scanners A scanner comparison against whatever happens to be running is a number, not a comparison. Here is the fixture set — known-bad images pinned by digest — that makes tool claims testable.
security What Key Rotation Actually Stops (and What It Doesn't) Rotating an age key re-encrypts secrets/db.enc.env to a new recipient list going forward. It does nothing to the plaintext an old key already read, and nothing to the ciphertext still sitting in earlier git commits.
sops Keeping Secrets in a Private Git Repo Without Actually Leaking Them secrets/db.enc.env is committed to a private GitHub repo, key names visible, values encrypted — and two independent age keys, one per machine, mean neither one alone has to be shared with the other.
traefik make check: A Cheap Smoke Test Before You Break Prod Two commands, a few seconds, no container ever bound to port 443 — make check validates the compose file and boots Traefik once against the static config before docker compose up ever touches the box actually serving nissaar.com.
traefik Convention Over Configuration: Adding a Service With Zero Router Labels No Host(...) rule appears anywhere in the traefik-selfhosted repo — the hostname for every service is derived from the container name by Traefik's defaultRule, and that one convention is most of what makes adding a service cheap.
platform-engineering The Registry Routing Campaign: Two of Nine, and Why It Goes One at a Time Routing upstream registries through Harbor is three separate jobs per registry — create the cache, enable the rule, move the workloads — and the campaign only works done one registry at a time, safest first.
docker Three Docker Networks, Fixed Subnets, One Reason: Firewall Rules That Don't Move frontend, socket, and backend are declared with fixed CIDR blocks on vmi2633427 for a reason that has nothing to do with routing and everything to do with what a firewall rule can trust.
kyverno A Policy Bundle With One Wrong Document Is a Silent No-Op A policy file carrying its companion ClusterRole made `kyverno apply` report 'Applying 0 policy rule(s)' and exit 0 — a green CI gate enforcing nothing. The fix is to assert the rule count, not the exit code.
docker Don't Give Your Reverse Proxy Root on the Host Traefik needs to know which containers exist and what labels they carry — it does not need exec, write, or image management. tecnativa/docker-socket-proxy is the difference between those two things.
kyverno Kyverno Test Goes Green When You Weaken a Policy A negative control on `kyverno test` found it is direction-asymmetric: assert `result: fail` on a resource the policy now lets through, and it prints 'Want fail, got pass' — then reports 25 tests passed and exits 0.
traefik The TLS Handshake Nobody at Home Sees: Full vs Full-Strict Behind Cloudflare Traefik on vmi2633427 issues no certificates and holds no ACME credentials — the browser's cert and the origin's cert are two entirely different documents, and closing the gap between them is one flag in Cloudflare's dashboard.