← Back to index

Engineering ·May 21, 2026 ·1 min read

I Rebuilt My Resume Site into a Self-Hosted Blogging Platform

How a static resume evolved into a bilingual blog with its own backend, custom comments, PWA support, and offline reading

I rebuilt my resume website into a fully self-hosted blogging platform.

It started as: Astro + resume.json + Cloudflare Pages → just a static resume. Done.

Then it turned into:

  • Posts stored in my own DB
  • Custom comments (no Giscus)
  • Self-built subscriptions & push notifications
  • Spring Boot + Postgres + Cloudflare Tunnel
  • Frontend still pure static

Yes, the counterintuitive part: I have a backend, but I keep the frontend static.

Why?

  • SEO needs full content
  • Fast first paint (CDN serves HTML directly)
  • If the backend dies, the site still lives

Real-time updates? Don’t care. Staying alive matters more.


But static has a problem:

I hit “publish” → nothing changes

I tried:

  1. Cloudflare deploy hooks → useless (I don’t use it to build)
  2. SSR → too heavy, dropped it
  3. Trigger GitHub Actions → ✅

Final setup:

Backend publish → trigger CI → live in seconds


The fun part: the pitfalls

  • Cloudflare Bot Fight Mode → flagged my CI as a bot → build succeeded, but posts were empty

    Fix: → spoof a real browser User-Agent


  • rsync without --delete

    → old classes stayed on the server → got compiled into the jar → login always returned 401

    Local worked. Production broke. Absolute nightmare.


  • Web Push library

    → compiles fine → crashes at runtime

    Because: → missing BouncyCastle


What this became:

Static frontend + self-hosted backend + automated deploy + custom push


The core idea is simple:

It’s not about making it work. It’s about what still works when things break.


Now?

I hit “publish” A few seconds later, it’s live on my domain.

The entire pipeline is mine.

Feels good.

Letters

Loading comments…