Skip to content
Nizar Abubaker

Essay1 min read

How this site is built — and what I left out

A personal website is a small system with the same questions as a big one: where content lives, who can change it, how it is cached and what happens when something fails.

A personal website is a small system. It still has to answer the same questions as a large one: where does content live, who can change it, how is it cached, how is it found, and what happens when something fails?

This note is the short tour.

Three services and a database

The public site and the CMS are one Next.js application. Content, authentication, media and search live in a NestJS API. Everything is stored in PostgreSQL. An Nginx container in front routes requests and serves uploaded media directly from disk.

That is the whole architecture. It runs with docker compose up -d on a single small server.

Request path

  1. Edge

    • Nginx

  2. Rendering

    • Next.js

  3. Content

    • NestJS API

  4. State

    • PostgreSQL

    • Media volume

Caching: one tag to rule them all

Pages are rendered on the server and cached. Every request the site makes to the API is tagged content. When anything is saved in the CMS, the API asks Next.js to invalidate that tag, and the next visitor gets a fresh page.

Fine-grained invalidation is possible, but a project title appears on the homepage, in the technology map, in related projects and in search. Tracking those dependencies would be more code than the rest of the caching layer. For a site with a few hundred pages, invalidating everything costs nothing.

What I left out

  • No Redis. Rate limits and caches live in memory; there is one API instance.
  • No Elasticsearch. PostgreSQL full-text search handles English and Arabic, with a generated, weighted index column.
  • No Kubernetes, no microservices. Two application containers is the right number.

Each of these is a reasonable choice for a different problem. None of them would make this site more credible, memorable, useful or human — which was the test for everything that went in.