LumiBaseDocs

Local Development

Prerequisites: Node.js ≥ 22, pnpm ≥ 9, Docker + Docker Compose, Git ≥ 2.40

Quick start

bash
# 1. Clone the repository
git clone https://github.com/khuepm/lumibase.git
cd lumibase

# 2. Install dependencies
pnpm install

# 3. Copy and configure environment
cp .env.example .env
# Edit .env — see docs/en/deployment/environment-variables.md

# 4. Start infrastructure (PostgreSQL, Redis, MinIO, MeiliSearch, imgproxy)
docker compose -f docker/docker-compose.yml up -d

# 5. Run database migrations
pnpm db:migrate

# 6. Start all dev servers
pnpm dev

Services running:

ServiceURLDescription
CMS APIhttp://localhost:1989Hono REST + WebSocket API
Studiohttp://localhost:2026Admin SPA
Docs viewerhttp://localhost:5174This docs site
PostgreSQLlocalhost:5432Database
Redislocalhost:6379Cache + queues
MeiliSearchhttp://localhost:7700Search
Bull Boardhttp://localhost:3001Queue dashboard
MinIOhttp://localhost:9000 (console :9001)S3-compatible object storage
imgproxyhttp://localhost:8080Image transformation

Running individual services

bash
# CMS API only
pnpm -F @lumibase/cms dev        # Hono with hot-reload (port 1989)

# Studio only
pnpm -F @lumibase/studio dev     # Vite SPA (port 2026)

# Docs only
pnpm -F @lumibase/docs dev       # Vite docs (port 5174)

First-time setup wizard

On first run, the CMS API detects an empty database and activates the setup wizard. Visit http://localhost:1989/setup to:

  1. Create the first admin user
  2. Set the site name and default language
  3. Configure the admin panel URL (security through obscurity)

Environment file

Minimum .env for local dev:

env
# Runtime
LUMIBASE_ENV=development
LUMIBASE_RUNTIME=docker
LUMIBASE_DEV_AUTH=true         # Skip Logto auth locally
JWT_SECRET=local-dev-secret-min-32-chars-long

# Database
DATABASE_URL=postgres://postgres:postgres@localhost:5432/lumibase

# Cache
REDIS_URL=redis://localhost:6379

# Search
MEILISEARCH_URL=http://localhost:7700
MEILISEARCH_API_KEY=masterKey

# AI (optional for local dev)
LLM_PROVIDER=echo              # Use echo mock — no API key needed
# Optional real provider smoke tests:
# LLM_PROVIDER=openai
# LLM_MODEL=gpt-4.1-nano
# OPENAI_API_KEY=...
# LLM_PROVIDER=gemini
# LLM_MODEL=gemini-3.5-flash
# GEMINI_API_KEY=...

Database management

bash
# Generate a new migration after schema changes
pnpm db:generate

# Check connectivity, current version, and pending migrations without applying DDL
pnpm db:migrate:preflight

# Apply pending migrations
pnpm db:migrate

# Print the current migration version
pnpm db:migrate:version

# Open Drizzle Studio (database GUI)
pnpm db:studio

# Seed development data
pnpm db:seed-dev

Testing

bash
# Run all tests
pnpm test

# Run tests in a specific package
pnpm -F @lumibase/cms test

# Watch mode
pnpm -F @lumibase/cms test --watch

# Type-check all packages
pnpm typecheck

# Lint all packages
pnpm lint

Simulating Cloudflare Workers locally

bash
# The CMS dev server already runs under Wrangler
pnpm -F @lumibase/cms dev

# This uses wrangler.toml and miniflare for:
# - KV (CONFIG_CACHE) → in-memory
# - R2 (MEDIA) → local ./tmp/r2
# - Durable Objects (SITE_ROOM) → local simulation
# - Hyperdrive → direct DB connection (no pooling)

Note: LUMIBASE_RUNTIME is automatically set to cloudflare when using Wrangler.


Common issues

Port conflicts

If ports are already in use, override the published container port in docker/.env:

env
CMS_PORT=1990

Studio's dev port is set in apps/studio/vite.config.ts (server.port: 2026) and has no environment-variable override. Pass the port to Vite instead:

bash
pnpm -F @lumibase/studio dev -- --port 2027

Docker not starting

bash
# Check logs
docker compose -f docker/docker-compose.yml logs

# Force recreate
docker compose -f docker/docker-compose.yml up -d --force-recreate

Type errors after git pull

Schema or package changes may require regenerating types:

bash
pnpm db:generate
pnpm install  # Update pnpm-lock if packages changed
pnpm typecheck

MeiliSearch index out of sync

bash
# Reindex all searchable collections
curl -X POST http://localhost:1989/api/v1/search/reindex \
  -H "Authorization: Bearer <admin-token>" \
  -H "X-Lumi-Site: <your-site-id>"
Last modified: 26/09/2026