Skip to main content
Local development uses WORKSPACE_MODE=local, which replaces per-user Kubernetes pods with a single daemon process on your machine. It is the fastest way to work on the application.

Requirements

  • Bun 1.3 or later
  • Docker with Compose, for PostgreSQL
  • Optionally recoll, recollindex, and rg for document-search testing

Set up

1

Start PostgreSQL

2

Configure the environment

Replace the placeholder values for BETTER_AUTH_SECRET and SETTINGS_ENCRYPTION_KEY. Both must be at least 32 characters.
3

Install and migrate

bash bun install bun run db:migrate
4

Run the workspace daemon

In its own terminal. The daemon uses a directory in your project as the workspace home rather than touching your real one.
5

Run the application

In a second terminal:
Open http://localhost:3000 and complete setup. The first successful setup request becomes the administrator.
In local mode every user shares one daemon and one home directory. This is fine for development and completely unsuitable for anything multi-tenant.

Environment reference for local mode

To use a model server on your own machine, such as Ollama or vLLM, set ALLOW_PRIVATE_EGRESS=true and ALLOW_INSECURE_HTTP=true. These weaken the outbound URL guard, so only enable them locally.

Checks before opening a pull request

bun test is hermetic and never touches a database. Database-backed tests are a separate suite that needs a reachable DATABASE_URL:
Validate the chart when you change it:

Database migrations

Migrations in drizzle/ are written by hand, not generated. The Drizzle schema in src/server/schema.ts describes the current shape for the query builder; the SQL files describe how an existing database reaches that shape. drizzle/meta/ intentionally carries no per-migration snapshots, so bun run db:generate has no baseline to diff against and emits the entire schema as a new migration. Applying that to a populated database fails with relation already exists and the rollout’s migrate init container crash-loops. Use it only to read a suggested diff, never as the committed file. To add a migration:
  1. Change src/server/schema.ts.
  2. Write drizzle/000N_<name>.sql containing only the incremental change, using IF NOT EXISTS / IF EXISTS so a re-run is harmless.
  3. Append a matching entry to drizzle/meta/_journal.json. Keep the hand-assigned when values sequential (1770000000000 + idx * 1000); the runner orders by idx, and a stable value keeps diffs readable.
  4. Apply it: bun run db:migrate.
Verify both paths before committing — a fresh database and an upgrade from the previous migration must end up with the same schema:
In Kubernetes, the chart applies migrations from an init container on every rollout, so a bad migration blocks the deployment rather than corrupting data.

Project layout