← Blog

Building felps.zip (with OpenCode)

How this blog runs on Nginx + Hono, Markdown in Tigris, and what OpenCode helped automate.

This site is my personal portfolio/blog at felps.zip, inspired by the clean structure and typography of thdxr.com.

The key constraints:

  • Every article is stored as a real Markdown file.
  • Post pages must ship real SEO/OG tags (no JS-only rendering).

Architecture

The project runs as two services:

  • Nginx (web) serves static assets and reverse-proxies requests.
  • Node.js + Hono (api) stores Markdown in Tigris (S3-compatible) and server-renders HTML for / and /post/:slug.

Nginx proxies these paths to the API:

  • / (homepage HTML)
  • /post/:slug (post HTML)
  • /api/* (JSON + publish endpoints)

This keeps the public origin as Nginx while still returning server-rendered HTML that crawlers and link unfurlers can read.

Content model

Each post is stored as:

  • posts/<slug>.md in Tigris

Posts use YAML frontmatter:

  • title, description, date (YYYY-MM-DD)
  • optional: tags, draft, og_image

Draft posts are hidden from the homepage and public API by default.

Publishing over HTTP

Publishing is uploading raw Markdown:

  • PUT /api/posts/:slug
  • Content-Type: text/markdown; charset=utf-8
  • Authorization: Bearer <ADMIN_TOKEN>

Deleting a post is:

  • DELETE /api/posts/:slug

Where OpenCode helped

OpenCode accelerated the build by handling the glue work quickly:

  • scaffolded the web (nginx) + api (Hono) split
  • wired routes and reverse proxy layout
  • implemented Markdown frontmatter parsing and Markdown-to-HTML rendering
  • implemented raw-markdown publishing endpoints
  • set up local Docker dev so behavior matches production (S3-compatible storage, same content flow)
  • matched the target page structure so the site feels close to thdxr

That let me focus on content and iteration instead of repeating setup steps.

Next steps

  • Upload pp.jpg to Tigris and set AUTHOR_AVATAR_URL
  • Add media upload support (optional) for post images/files
  • Add RSS and sitemap generation from the post index