Skip to content

Getting started locally

Everything runs on one machine: the Payload backend, the Astro site, Postgres and Meilisearch in Docker, and Ollama for embeddings. Budget about twenty minutes, most of it downloads.

Tool Why Install
Node 22 (see .nvmrc) backend and frontend nvm install
pnpm backend package manager corepack enable pnpm
Docker Desktop Postgres 17, Meilisearch 1.53.1, the WordPress source DB for migrations docker.com
Ollama with bge-m3 query embeddings for semantic search, and the sentence/passage index builds brew install ollama && ollama pull bge-m3
ffmpeg, uv, a Hugging Face login only if you run the transcription worker see worker/README.md
Terminal window
cd backend
cp .env.example .env # then fill DATABASE_URL, PAYLOAD_SECRET, CRON_SECRET, MEILI_*
docker compose up -d postgres meilisearch
pnpm install --ignore-workspace # note the flag; see package.json "ii"
pnpm payload migrate # schema lives in src/migrations, push is off on purpose
pnpm dev # http://localhost:3001 — admin at /admin

Data: restore a dump into the local Postgres rather than migrating from WordPress again. The nightly production dump lands on the Hangar box (see Backups and restore); pg_restore --no-owner --no-acl -d "$DATABASE_URL" kalelm-YYYY-MM-DD.dump.

Search index: pnpm migrate:wp index builds the keyword indexes from the local database in about two minutes. sentences and passages build the vector indexes and take hours on a GPU; copy data.ms from another same-version instance instead when one exists.

Terminal window
cd frontend
npm install
PUBLIC_API_URL=http://localhost:3001 npm run dev # http://localhost:4321; the gate expects 4322, see scripts/frontend-dev.sh

PUBLIC_API_URL is baked in at build time by Astro, so a production build must be made with the production API URL; scripts/deploy-hangar.sh frontend does that.

Terminal window
pnpm verify # all sections
pnpm verify pipeline # one section

It needs Postgres, the backend on 3001, the frontend on 4322, Meilisearch on 7701 and Ollama running. Each section says what it exercises. A Stop hook in the owner’s Claude setup runs it at the end of every turn and refuses to finish while it fails; if Meilisearch is stopped for maintenance, the gate fails for that reason alone.

The transcription worker is a separate Python program with its own README in worker/. Locally it can be started from the admin panel once PIPELINE_WORKER_PYTHON in .env points at a venv that has its requirements.

Terminal window
cd docs && npm install && npm run dev # this site, at http://localhost:4321

Pages are Markdown in src/content/docs/; screenshots in public/images/. Publish with scripts/deploy-hangar.sh docs.