<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Mr Hoelee</title><description>Personal blog of Lee Teong Hoe (Mr Hoelee) — full-stack engineering, DevOps &amp; self-hosting, AI automation, and Web3 experiments.</description><link>https://blog.hoelee.com/</link><language>en</language><item><title>Replacing RDPGuard With IPBan: The Traps Nobody Documents</title><link>https://blog.hoelee.com/posts/replacing-rdpguard-with-ipban/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/replacing-rdpguard-with-ipban/</guid><description>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.</description><pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>windows</category><category>security</category><category>rdp</category><category>ipban</category><category>rdpguard</category><category>brute-force</category><category>firewall</category><category>self-hosting</category></item><item><title>Your Own Speech-to-Text Server: Faster Than Typing, Private by Default</title><link>https://blog.hoelee.com/posts/self-hosted-speech-to-text-api/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/self-hosted-speech-to-text-api/</guid><description>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.</description><pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>whisper</category><category>cuda</category><category>stt</category><category>n8n</category><category>nginx</category><category>self-hosting</category><category>ai</category></item><item><title>Upgrading n8n v1 to v2: Seven Deprecations in One Log File</title><link>https://blog.hoelee.com/posts/n8n-v1-to-v2-upgrade-gotchas/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/n8n-v1-to-v2-upgrade-gotchas/</guid><description>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.</description><pubDate>Fri, 18 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>n8n</category><category>docker</category><category>upgrade</category><category>self-hosting</category><category>debugging</category><category>automation</category></item><item><title>I Ran a Text-to-Speech Service for a Year on Two Cron Containers</title><link>https://blog.hoelee.com/posts/running-tts-as-a-service-with-token-sidecars/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/running-tts-as-a-service-with-token-sidecars/</guid><description>A reading app needed TTS. Cloud free tiers expire tokens in 10 minutes and 1 hour. Here&apos;s the sidecar pattern that kept Azure and Google voices working for a year with no secrets in any workflow.</description><pubDate>Fri, 18 Sep 2026 00:00:00 GMT</pubDate><category>ai</category><category>n8n</category><category>tts</category><category>azure</category><category>google-cloud</category><category>docker</category><category>automation</category><category>sidecar</category></item><item><title>Self-Healing Access Control for Digital Goods: NocoDB, n8n, and AList</title><link>https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/self-healing-digital-goods-entitlements/</guid><description>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.</description><pubDate>Fri, 18 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>n8n</category><category>nocodb</category><category>alist</category><category>access-control</category><category>docker</category><category>automation</category><category>digital-goods</category></item><item><title>Shipping an AI Photo Editor as a WordPress Plugin: 22 Versions of Hard Lessons</title><link>https://blog.hoelee.com/posts/shipping-an-ai-photo-editor-as-a-wordpress-plugin/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/shipping-an-ai-photo-editor-as-a-wordpress-plugin/</guid><description>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.</description><pubDate>Fri, 18 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>wordpress</category><category>php</category><category>fal-ai</category><category>docker</category><category>ai-image</category><category>javascript</category></item><item><title>The Corruption Came Back on Different Drives — the Cause Was TRIM, Not the SSDs</title><link>https://blog.hoelee.com/posts/the-cause-was-trim-not-the-ssds/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/the-cause-was-trim-not-the-ssds/</guid><description>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.</description><pubDate>Fri, 18 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>unraid</category><category>btrfs</category><category>trim</category><category>ssd</category><category>raid</category><category>data-loss</category><category>smart</category><category>troubleshooting</category><category>seagate</category></item><item><title>How I Self-Hosted a Mem0 Memory Stack (So My AI Agent Remembers)</title><link>https://blog.hoelee.com/posts/self-hosting-mem0-memory-stack/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/self-hosting-mem0-memory-stack/</guid><description>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&apos;s.</description><pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>mem0</category><category>docker</category><category>postgres</category><category>pgvector</category><category>litellm</category><category>ai</category><category>sharing</category></item><item><title>I Was About to RMA This SSD — the Fault Was a SATA Cable</title><link>https://blog.hoelee.com/posts/that-dying-ssd-was-just-a-bad-sata-cable/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/that-dying-ssd-was-just-a-bad-sata-cable/</guid><description>A Seagate IronWolf 110 SSD threw WRITE FPDMA timeouts, failed mkfs with &apos;superblock magic doesn&apos;t match&apos;, 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.</description><pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>unraid</category><category>sata</category><category>ssd</category><category>storage</category><category>troubleshooting</category><category>smart</category><category>fio</category><category>cable</category></item><item><title>When SMART Says Healthy and Your RAID Is Silently Corrupting Data</title><link>https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/when-smart-says-healthy-but-your-raid-is-corrupting-data/</guid><description>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.</description><pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>unraid</category><category>btrfs</category><category>nvme</category><category>raid</category><category>storage</category><category>data-loss</category><category>troubleshooting</category></item><item><title>Why Unraid Hangs When You Stop the Array With a Swapfile — and the Fix</title><link>https://blog.hoelee.com/posts/unraid-stop-array-hangs-on-swapfile/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/unraid-stop-array-hangs-on-swapfile/</guid><description>My Unraid array stop hung forever at unmounting disks because an 8 GB btrfs swapfile pinned /mnt/cache. Root cause, the /boot/config/stop trap, and two User Scripts that fix it.</description><pubDate>Tue, 15 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>unraid</category><category>swap</category><category>btrfs</category><category>zram</category><category>docker</category><category>user-scripts</category></item><item><title>Passbolt UI Kept Hanging — Three Failure Modes From One Missing Config File</title><link>https://blog.hoelee.com/posts/passbolt-hang-three-failure-modes/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/passbolt-hang-three-failure-modes/</guid><description>My self-hosted Passbolt returned 504s for weeks: a null GPG fingerprint stalled email delivery, a container recreate wiped the fix, and ssl.force behind a proxy caused a redirect loop.</description><pubDate>Sun, 13 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>passbolt</category><category>docker</category><category>gpg</category><category>smtp</category><category>reverse-proxy</category><category>portainer</category></item><item><title>Scraping a Bot-Walled Marketplace With a Warm Browser Session</title><link>https://blog.hoelee.com/posts/scraping-bot-walled-marketplace-warm-browser-session/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/scraping-bot-walled-marketplace-warm-browser-session/</guid><description>Scraping bot-walled marketplace listings for a client&apos;s used-electronics business: warm CDP session, fail-fast health checks, split-wait rendering.</description><pubDate>Sun, 13 Sep 2026 00:00:00 GMT</pubDate><category>engineering</category><category>scraping</category><category>cdp</category><category>headless-chrome</category><category>anti-bot</category><category>shopee</category><category>python</category></item><item><title>Best AI Video Generators in 2026: Free vs Paid, and My LTX-2.3 Test</title><link>https://blog.hoelee.com/posts/best-ai-video-generators-2026/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/best-ai-video-generators-2026/</guid><description>Compare the best AI video generators in 2026 — free vs paid plans, real pricing, local open-weight models, and my hands-on LTX-2.3 test.</description><pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate><category>ai</category><category>ai-video</category><category>video-generation</category><category>ltx</category><category>open-weights</category><category>pricing</category><category>veo</category></item><item><title>How I Made My Own Songs with Suno AI</title><link>https://blog.hoelee.com/posts/how-i-made-my-own-songs-with-suno-ai/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/how-i-made-my-own-songs-with-suno-ai/</guid><description>I wrote the lyrics, tuned the prompts, and shipped seven songs with Suno AI — folk ballads, a kids&apos; tune, an anime-style Heart Sutra. Full workflow + the tracks.</description><pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>suno</category><category>ai-music</category><category>music</category><category>lyrics</category><category>prompting</category><category>ai</category></item><item><title>How I Built an AI Furniture Compositing Demo With FLUX.1 Kontext</title><link>https://blog.hoelee.com/posts/ai-furniture-compositing-with-flux-kontext/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/ai-furniture-compositing-with-flux-kontext/</guid><description>Compositing furniture photos into styled room scenes with fal.ai FLUX.1 Kontext — the multi-image endpoint, the tainted-canvas fix, and why prompt enhancement had to go.</description><pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>fal-ai</category><category>flux</category><category>ai-image</category><category>javascript</category><category>canvas</category><category>ecommerce</category></item><item><title>Syncing a Self-Improving AI Agent Across Machines</title><link>https://blog.hoelee.com/posts/syncing-a-self-improving-ai-agent-across-machines/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/syncing-a-self-improving-ai-agent-across-machines/</guid><description>How I sync my Hermes agent&apos;s skills, config, and cron jobs between two PCs with a git-backed profile distribution — and why I sync manually instead of on a cron.</description><pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>hermes</category><category>git</category><category>gitea</category><category>ai-agents</category><category>devops</category><category>sync</category></item><item><title>Using Chinese LLM APIs From Malaysia: What Actually Works</title><link>https://blog.hoelee.com/posts/using-chinese-llm-apis-from-malaysia/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/using-chinese-llm-apis-from-malaysia/</guid><description>Using Chinese LLM APIs (GLM-5.3, DeepSeek V4) from Malaysia: how I paid in RMB, handled phone verification, and which providers actually work.</description><pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate><category>ai</category><category>llm</category><category>api</category><category>deepseek</category><category>glm</category><category>alipay</category><category>malaysia</category></item><item><title>The NocoDB Attachment That Wouldn&apos;t Update (and a Regex That Missed)</title><link>https://blog.hoelee.com/posts/the-nocodb-attachment-that-wouldnt-update/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/the-nocodb-attachment-that-wouldnt-update/</guid><description>Two small gotchas from backfilling 300 rows: NocoDB ignores a path change when the attachment keeps its id, and a lookahead regex silently skipped URLs without a file extension.</description><pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate><category>notes</category><category>nocodb</category><category>backfill</category><category>python</category><category>regex</category><category>data-pipeline</category></item><item><title>Why Your Headless Browser Can&apos;t Scrape Everything</title><link>https://blog.hoelee.com/posts/why-your-headless-browser-cant-scrape-everything/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/why-your-headless-browser-cant-scrape-everything/</guid><description>Two second-hand marketplaces, two very different walls: Goofish blocks a headless browser with &apos;illegal access&apos; while Carousell keeps serving data. The lesson is to read how a page delivers data before you reach for Playwright.</description><pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>scraping</category><category>playwright</category><category>browserless</category><category>docker</category><category>goofish</category><category>carousell</category><category>anti-bot</category></item><item><title>How I Vetted 20 VPS Providers in Three Hours with Parallel Subagents</title><link>https://blog.hoelee.com/posts/how-i-vetted-20-vps-providers-with-parallel-subagents/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/how-i-vetted-20-vps-providers-with-parallel-subagents/</guid><description>A case study in orchestrating parallel AI subagents to run due diligence on 20 hosting providers — WHOIS, AUP, and reputation checks — collapsing a multi-hour research task into a structured, verifiable vendor scorecard.</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>ai-orchestration</category><category>subagents</category><category>due-diligence</category><category>hosting</category><category>devops</category></item><item><title>Hardening a Tor Onion Service: What Actually Matters</title><link>https://blog.hoelee.com/posts/hardening-a-tor-onion-service/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/hardening-a-tor-onion-service/</guid><description>Out of curiosity I mirrored my portfolio and git server onto the darknet. Here&apos;s the hardening that held, the parts that silently broke, and whether it&apos;s worth offering to clients.</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>tor</category><category>docker</category><category>security</category><category>self-hosting</category><category>networking</category></item><item><title>Automating CyberPanel Without the UI: Reverse-Engineering an Undocumented v2 API</title><link>https://blog.hoelee.com/posts/automating-cyberpanel-without-the-ui/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/automating-cyberpanel-without-the-ui/</guid><description>CyberPanel v2 killed the documented JSON API and left only the Angular UI&apos;s own session+CSRF endpoints. Here&apos;s the exact auth flow and how I found the real functions behind the pages.</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>cyberpanel</category><category>api</category><category>reverse-engineering</category><category>automation</category><category>django</category><category>self-hosting</category><category>curl</category></item><item><title>Authentik 2025.8 to 2026.8: The Breakable Parts Nobody Warns You About</title><link>https://blog.hoelee.com/posts/authentik-major-upgrade-gotchas/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/authentik-major-upgrade-gotchas/</guid><description>A year&apos;s worth of authentik major-version upgrade pain: storage mount changes, RBAC session cleanup, trusted proxies, and the authorization_flow vs authentication_flow mix-up that broke SSO.</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>authentik</category><category>sso</category><category>docker</category><category>portainer</category><category>self-hosting</category><category>oidc</category><category>upgrade</category></item><item><title>How to Verify a Hosting Provider Before You Buy</title><link>https://blog.hoelee.com/posts/how-to-verify-a-hosting-provider-before-you-buy/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/how-to-verify-a-hosting-provider-before-you-buy/</guid><description>A reusable checklist for separating real hosting claims from marketing: check the domain age against the &apos;since&apos; claim, read the AUP for silent disqualifiers, and cross-check reputation on third-party sources.</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><category>tutorials</category><category>hosting</category><category>vps</category><category>due-diligence</category><category>whois</category><category>devops</category></item><item><title>Why Telegram Bot Notifications Die: IPv6, DNS, and a 400 That Took a Day</title><link>https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/why-telegram-bot-notifications-die/</guid><description>A debugging story: a Dockerized telegram monitor whose sendPhoto calls returned 400 from nginx/1.30.1 while getMe worked fine — an IPv6-only DNS answer, a wrong extra_hosts IP, and a multipart join that corrupted JPEG bytes.</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><category>devops</category><category>docker</category><category>telegram</category><category>python</category><category>dns</category><category>ipv6</category><category>debugging</category><category>portainer</category></item><item><title>How I Built the DigiKedai Telegram AI Bot</title><link>https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/how-i-built-the-digikedai-telegram-bot/</guid><description>A customer-support AI bot that answers questions and provisions free-trial accounts over Telegram and WhatsApp — TypeScript, grammY, a Cloudflare tunnel webhook, and a self-hosted LiteLLM gateway.</description><pubDate>Sun, 06 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>telegram</category><category>docker</category><category>cloudflare</category><category>litellm</category><category>typescript</category><category>ai</category></item><item><title>Hello, World — About This Blog</title><link>https://blog.hoelee.com/posts/hello-world/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/hello-world/</guid><description>What this blog is for: technical writing, self-hosting experience, and a record of what I build and learn.</description><pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate><category>notes</category><category>intro</category></item><item><title>How I Host This Blog: Astro, Gitea Actions, and Self-Hosted CI/CD</title><link>https://blog.hoelee.com/posts/how-i-host-this-blog/</link><guid isPermaLink="true">https://blog.hoelee.com/posts/how-i-host-this-blog/</guid><description>A walkthrough of the end-to-end pipeline that builds and serves this site — git-as-CMS, a self-hosted runner on my unRaid server, and Cloudflare in front.</description><pubDate>Fri, 04 Sep 2026 00:00:00 GMT</pubDate><category>case-studies</category><category>astro</category><category>gitea</category><category>ci-cd</category><category>self-hosting</category><category>docker</category><category>cloudflare</category></item></channel></rss>