Back to path
BeginnerTradepost · Project 1 of 12 ~3h· 5 milestones

Run it locally and speak HTTP to it

You just cloned the Tradepost starter repo. It has a Fastify API, a Drizzle schema, and Postgres and Redis wired up in docker-compose.yml, but right now none of it runs.

Docker Compose orchestration and healthchecksEnvironment variable configuration for local devHTTP verbs and status codescurl and jq for API testingFastify v5 request lifecycle and route schemasReading pino structured logsReading and mapping an OpenAPI specPostgres connection basics

What you'll build

You finish able to boot Tradepost locally in under two minutes, curl its two live endpoints and read the status codes and headers correctly, and trace one request from the wire to Postgres and back, the base skill every later rung builds on.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

docker-compose.ymlyaml
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: tradepost
      POSTGRES_PASSWORD: tradepost
      POSTGRES_DB: tradepost
    ports:
      - "5432:5432"
    volumes:
      - tradepost_pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U tradepost -d tradepost"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

volumes:
  tradepost_pgdata:

Reading this file

  • pg_isready -U tradepost -d tradepostCompose waits for this to succeed before marking postgres healthy, so the API never races a container that is up but not yet accepting queries.
  • POSTGRES_PASSWORD: tradepostLocal-only credential, must match DATABASE_URL in your .env exactly.
  • "CMD", "redis-cli", "ping"Runs redis-cli ping directly inside the container as the healthcheck.
  • "5432:5432"Maps container port to the same host port, must be free on your machine or you need to change both sides.
  • tradepost_pgdata:/var/lib/postgresql/dataNamed volume, data persists across docker compose down but is deleted by docker compose down -v.

This compose file runs ONLY postgres and redis, never the API itself, the API always runs on your host with pnpm dev so you can see its logs and restart it fast.

That's 1 of 6 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    Boot Postgres and Redis with Compose

    5 guided steps

    A container that is up is not the same as a container that is ready. Postgres accepts TCP connections before it can actually run queries, so if the API connects too early it fails with a confusing error that has nothing to do with your code. Healthchecks are how Compose (and later, orchestrators) know the difference between started and ready.

  2. 2

    Configure .env and run the API

    5 guided steps

    The API does not know where Postgres and Redis live until you tell it, and the startup log is the API telling you, in one line, whether it found them. Reading that line correctly now saves you from guessing at connection errors for the rest of the ladder.

  3. 3

    Speak HTTP with curl

    5 guided steps

    For the rest of this ladder curl is your browser. You need to be fluent in reading a status line, the headers that matter (content-type, content-length), and the body, without a devtools panel doing it for you.

  4. 4

    Trace one request through the code

    5 guided steps

    Every later rung adds a layer to this same request path: auth checks, transactions, idempotency, caching. If you cannot point to exactly where in the code a request currently goes, you will not be able to reason about where a new layer should sit.

  5. 5

    Read the OpenAPI docs it serves

    5 guided steps

    openapi.yaml and the Fastify route schema are two views of the same contract. If they drift apart, /docs starts lying to the merchants integrating against it. Learning to cross-check them now is what makes rung 3, where you design the error and versioning contract, make sense.

What's inside when you start

3 starter files, ready to clone
5 guided milestones
3 full reference solutions
6 code blocks explained line-by-line
5 "is it working?" checks
6 interview questions it prepares you for

You'll walk away with

Postgres and Redis running locally via docker compose, both reporting (healthy)
The API running with pnpm dev, bound to :3000, with a clean pino startup log
A shell script of curl commands hitting /healthz and GET /v1/products with -i, showing correct status codes and headers
A one-paragraph written trace of a single request from route registration through Drizzle to the Postgres row and back
Confirmation that /docs and openapi.yaml agree with the route schema in src/routes/products.ts

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building