DEV Community

Cover image for Why I moved my blog off WordPress and into code
Abir Bhattacharyya
Abir Bhattacharyya

Posted on AI-assisted

Why I moved my blog off WordPress and into code

For a while my blog lived on a free WordPress.com plan. 10 years to be exact — roboinno.wordpress.com, no custom domain, "Powered by WordPress.com" in the footer. Ads banner all around and to get rid of it I had to subscribe monthly. It worked, and it actually built something real: a community of people who were curious just like me. But the ads, constant limitations and lack of modifications made the experience really bad. So bad that I wanted to self-host my own WordPress.

There are plenty of platforms where you can get a self-hosted WordPress blog running easily — Hostinger, for example, has genuinely cheap plans that give you a lot of control, though it adds up once you want something more serious. I looked at self-hosting WordPress on my Raspberry Pi instead, to get real code access. Docker, Cloudflare Tunnel, the whole setup — technically straightforward, a weekend project. But one Pi already runs my RL experiments and another home assistant. Putting a public-facing CMS — historically one of the most attacked platforms on the internet — on the same box as that is a bad trade. Not because it's hard to secure, but because the asymmetry is wrong: worst case for a hacked blog is embarrassing, worst case for a hacked home server is real data and potentially money.

So instead, this blog lives right in my hosteed website, in the same codebase as the rest of the site:

  • Every post is a folder — public/blog/<slug>/index.mdx — with its own images sitting right next to it. No separate media library to keep in sync.
  • Frontmatter (title, date, excerpt, tags) is just YAML at the top of the file, parsed at build time.
  • No database, no admin login, no PHP. It's a static export — there's genuinely nothing here for an attacker to brute-force.
  • Writing is: open the .mdx file, write, save, flip to a browser tab, refresh.

The subscriber list moved too — into Firestore now, with double opt-in confirmation and self-service unsubscribe, no cap and no cost as the list grows.

Originally posted on my blog — cross-posting the build logs here too.

Top comments (3)

Collapse
 
raknaos profile image
Raknaos

The asymmetry argument is the honest one and it's underrated: 'not because it's hard to secure, but because the worst cases are on different scales' is exactly why a public PHP admin does not belong next to boxes holding real data and money. A static export where the write path is a git commit moves the entire attack surface to the CDN, which is a trade most hobby bloggers would take if they priced it properly.

Folder-per-post with images next to the file is the part I keep envying -- no media library to desync means no silent rot. The subscriber list is the interesting exception: moving it to Firestore with double opt-in solves the cost problem, but the list is the one asset you can't regenerate if it goes wrong. Do you dump it to the repo on a schedule, or is the export path tested only when you actually need it?

Collapse
 
bathonspidey profile image
Abir Bhattacharyya

You mean the subscriber list? I do not dump it basically I used github actions to notify my subscribers directly via mail without using any other third parties. I wanted to make a self hosted git. I have self hosted runners in my Pi but to actually self host a git repo is a bit complex. I tried digging through it with mercurial but I need to gain more expertise before I can actually realize it but maybe soon if I keep improving my skills

Some comments may only be visible to logged-in visitors. Sign in to view all comments.