The short take
Two months ago I tore up the three‑year old WordPress mess and rebuilt OSINTSights on Cloudflare Workers + a tiny Hetzner ARM box because the marketing‑tech stack had eaten the personal‑publication stack. The old site was slow, overloaded with plugins, and throttling my ability to publish. The new stack is lighter, faster, and — crucially — lets a single operator (me) keep up with reality using AI as leverage, not as theater. Hosting and infra run me roughly $30/month (≈$360/year) total — cheap enough that complexity is no longer an argument.
Where it was and why it died
The old site: WordPress self‑hosted, roughly 8,000 articles, and a plugin tax that read like a small SaaS subscription list. The editor was sluggish; adding a feature meant another plugin, another update, another conflict. Content velocity was the bottleneck. I spent more time maintaining plugins and fighting editor quirks than producing or curating signals.
If you’ve spent time in the trenches you know how this plays out — the platform dictates cadence, not the author. For a one‑person publication, that’s a death sentence.
What I rebuilt and how it actually works
I rebuilt the public face on Cloudflare Workers (Next.js via @opennextjs/cloudflare). It’s snappy, caches predictably at the edge, and it doesn’t carry the runtime baggage of a PHP monolith. Storage is D1 (SQLite) for small, fast reads and R2 for images. Semantic search and dedup are handled by Vectorize; I treat a 0.92 cosine similarity as the cutoff for near‑identical content, combined with URL checks. Result: after dedup, the pipeline produces roughly 100 articles per day — real items, not repeated cruft.
The ingest and enrichment pipeline runs on a single ridiculously cheap Hetzner ARM box in a rootless Podman/Quadlet container. It’s Python 3.12 with APScheduler orchestrating jobs for ~30 RSS feeds, metadata enrichment, image generation via Flux 2 Klein, and two layers of AI: gpt‑5‑mini for content synthesis and Llama 4 Scout for metadata and tagging. Observability is light at the moment but usable — Gateway for metrics and alerts.
- Publish pipeline: ~30 RSS sources → dedup (URL + Vectorize @0.92) → generate/normalize content → push to Workers
- Auto‑posting: Mastodon + Facebook on publish; X and LinkedIn are queued next
- Admin: dashboard runs on the same Hetzner box, binds to loopback only and is accessed over private tunneling — no public admin surface
Security posture is pragmatic: rootless containers, ReadOnly=true where feasible, no_new_privileges, IaC via Terraform with weekly drift detection, and CSP implemented through Cloudflare Transform Rules — not Next.js middleware, which breaks rendering on Workers. I don’t need immutable‑infra theater; I need repeatable, auditable controls that don’t make publishing impossible.
Why this matters and what’s next
Big stacks sold me features I didn’t need and costs I didn’t want. They optimized for vendor lock and checkbox compliance, not for a single person trying to publish useful, timely content. AI changed the calculus: with cheap, capable models I can automate the boring parts of curation, surface duplicates, and keep pace with volume without hiring a content farm.
What I’m shipping next: better dedup tuning (vector thresholds and URL heuristics), X and LinkedIn posting, and the rest of the admin surface for pipeline monitoring, error triage, and log tailing. None of that requires another CMS migration; it requires disciplined engineering and a realistic security posture.
If you run a small publication and find yourself drowning in plugin updates, slow editors, and vendor roadmaps, do two things: 1) stop letting your stack dictate your cadence. 2) Move the public face to an edge platform with a small, reliable backing store, push ingest to a single small box if that fits your threat model, and instrument the hell out of it. The marginal cost is low; the reduction in friction is enormous.
Final point: the marketing‑tech stack ate the personal‑publication stack because it promised scale and delivered lock‑in. This approach gave me a lever to pry it back. If you care about being in the story instead of serving the dashboard, start using it.




