← all builds

From-Scratch Build · Backend

Lab Website Backend

The content engine behind a lab website — a headless CMS that stores every page, person and post in a database and serves it to a frontend over a REST API. Rebuilt from scratch to learn how a content backend models, secures and delivers data without rendering a single page itself.

Headless CMSNode.jsTypeScript REST APIDocker

What it is

A website with no pages

This is the half of the system that visitors never see. It renders nothing. Its entire job is to be a content backend: a place where editors define content types, fill them with data, and expose that data as a clean API for a separate frontend to consume.

I built it to learn the headless CMS pattern. Instead of writing models, an admin and an API by hand, a headless CMS gives you all three from a content schema you design in its dashboard — and then hands every editor a polished interface and every developer a typed REST endpoint.

The core idea I wanted to learn: content is a service. When the backend's only deliverable is well-structured JSON over an API, any number of frontends — a website, a mobile app, a screen in a lobby — can all draw from the same single source of truth.

The stack

Tools under the hood

The point of this rebuild was the toolchain. Here is what each piece actually does in the system.

platform

Headless CMS

A Node.js content platform that turns a schema into a database, an admin dashboard and a REST API — all generated, not hand-written.

language

TypeScript config

The server, database and API are configured in typed config files, so settings are checked and self-documenting.

content types

Schemas

Each content type — page, person, post — is defined as a schema; the CMS builds the table and the edit forms around it.

delivery

REST API

Every content type is exposed as an endpoint that returns JSON, protected by API keys and role-based permissions.

media

Upload pipeline

A managed uploads folder stores images and files, served back to the frontend by URL.

packaging

Docker + Compose

Separate dev and production Dockerfiles package the CMS and its database so deployments are reproducible.

Architecture

From schema to API response

A piece of content travels the same path from definition to delivery. Tracing it made the headless model click.

  1. Define a content type live

    In the dashboard you describe the fields of a "page" or "person"; the CMS scaffolds the database table.

  2. Edit in the admin live

    Editors fill in content through generated forms — no code, no database access required.

  3. Store in the database live

    Entries are persisted with their relations and uploaded media tracked alongside.

  4. Set permissions live

    Roles and API tokens decide which content types are public and which require a key.

  5. Serve over REST live

    A frontend requests an endpoint and receives the content as structured JSON.

  6. Deploy in a container live

    The whole CMS plus database ships via Docker for a consistent production environment.

How it runs

Boot the content engine

Standing the backend up is about preparing its environment and letting the CMS take over:

In my rebuild I focused on the content schema and the permissions layer — the two things that decide what the frontend is allowed to ask for.

Reflection

What rebuilding it taught me