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>.mdin 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/:slugContent-Type: text/markdown; charset=utf-8Authorization: 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.jpgto Tigris and setAUTHOR_AVATAR_URL - Add media upload support (optional) for post images/files
- Add RSS and sitemap generation from the post index