Hi, I'm Lee Teong Hoe.
A full-stack developer and DevOps engineer based in Malaysia. I build web apps (PHP/CodeIgniter, Java/Spring, TypeScript/React), self-host a ~140-container homelab, and run a website design & development business for Malaysian SMEs. I write here about what I learn and ship.
Latest posts
-
Replacing RDPGuard With IPBan: The Traps Nobody Documents
I migrated from paid RDPGuard 7.8.7 to open-source IPBan 4.1.0 — and hit three undocumented traps, including an uninstaller that would have silently unbanned 12 attackers.
-
Your Own Speech-to-Text Server: Faster Than Typing, Private by Default
I run a self-hosted speech-to-text API on a single GPU PC. Dictation works from Windows, iPhone, iPad and Android — private, unlimited, and about 5x faster than typing.
-
Upgrading n8n v1 to v2: Seven Deprecations in One Log File
My self-hosted n8n 1.x to 2.40.1 upgrade surfaced seven silent breakages at once — a telemetry schema rejection, deprecated webhook vars, and a DB override that quietly disabled the AI sandbox.
-
I Ran a Text-to-Speech Service for a Year on Two Cron Containers
A reading app needed TTS. Cloud free tiers expire tokens in 10 minutes and 1 hour. Here's the sidecar pattern that kept Azure and Google voices working for a year with no secrets in any workflow.
-
Self-Healing Access Control for Digital Goods: NocoDB, n8n, and AList
How I built a five-workflow entitlement system that grants, expires, and continuously repairs customer file access — with a build-time code-sharing trick and a public endpoint designed to leak nothing.
-
Shipping an AI Photo Editor as a WordPress Plugin: 22 Versions of Hard Lessons
From a single HTML file to a shipped WordPress plugin: the fal.ai async queue, a watermark that must never silently fail, optional lead capture, and five bugs that only appeared in production.
-
The Corruption Came Back on Different Drives — the Cause Was TRIM, Not the SSDs
Two weeks after a btrfs RAID1 pool corrupted on healthy-looking NVMe drives, the same all-zero checksum reappeared on a different drive stack. The culprit was queued TRIM (NCQ) on Seagate IronWolf 110 SSDs — a firmware bug FreeBSD blacklisted but Linux never did. How I caught it and the fix.
-
How I Self-Hosted a Mem0 Memory Stack (So My AI Agent Remembers)
A private, self-hosted memory layer for AI agents — mem0 API + LiteLLM + PostgreSQL with pgvector on a Synology NAS. Semantic memory under your control, not a third party's.
-
I Was About to RMA This SSD — the Fault Was a SATA Cable
A Seagate IronWolf 110 SSD threw WRITE FPDMA timeouts, failed mkfs with 'superblock magic doesn't match', and went silent — a textbook dying drive. I swapped one SATA cable and it formatted clean with zero errors. How to test before condemning a drive.
-
When SMART Says Healthy and Your RAID Is Silently Corrupting Data
A btrfs RAID1 pool on two healthy-looking NVMe drives quietly corrupted a Windows VM. How I caught it with a checksum forensic — and why the root cause (M.2 riser link fault vs batch defect) is still uncertain, with both drives now testing clean.