Local development

On this page

dembrane is several services with shared infrastructure, so the recommended way to develop is the devcontainer plus mprocs: the container provides Postgres, Redis/Valkey and Directus; mprocs runs the host processes (API, workers, scheduler, the two frontends). This page gets you from a fresh checkout to a running stack. For what each service is, see architecture; for how it ships, see deployment & releases. The operator-facing version of this - for people running dembrane outside our setup - is self-hosting.

What you’ll be running

Process (mprocs) Command Port
server uv run uvicorn dembrane.main:app --port 8000 --reload --loop asyncio :8000
workers uv run dramatiq-gevent --queues network --processes 1 --threads 10 dembrane.tasks -
workers-cpu uv run dramatiq --queues cpu --processes 1 --threads 1 dembrane.tasks -
scheduler uv run python -m dembrane.scheduler -
admin-dashboard pnpm run dev (in frontend/) :5173
participant-portal pnpm run participant:dev (in frontend/) :5174

Plus the infra from the devcontainer’s compose file: Postgres (with pgvector), Redis/Valkey, Directus (:8055), and optionally the agent service (:8001).

Note

:5173 is the host dashboard and :5174 is the participant portal - both are the same frontend/ codebase, served by two Vite dev servers so you can work on either in isolation. See architecture.

The devcontainer

Use the devcontainer for development - it configures and manages the services and their dependencies for you. Everything lives in echo/.devcontainer/:

Prerequisites: VS Code or Cursor with the Dev Containers extension, Docker, and WSL on Windows. (The echo/readme.md is the canonical, screenshot-level walkthrough - follow it for the exact click-path; this page is the orientation.) The toolchain is pnpm for the frontend and uv for the Python server - local entry points always go through uv run so env and deps stay consistent.

Tip

On this team's Macs the devcontainer runs on Podman, not Docker Desktop. If docker commands behave oddly, check which engine your editor is wired to.

Env files

Two services each need their own env file, both copied from a checked-in sample:

Key things to set in server/.env:

Important

There are two independent email senders: the Python app (SendGrid HTTP API, email.py) and Directus itself (SendGrid SMTP). They use different keys and config. Setting one does not affect the other. EU residency (SENDGRID_REGION=eu) must be set on both, with EU regional subuser keys. See echo/server/AGENTS.md.

S3: MinIO locally, or bring your own

You have two options for object storage:

Audio chunks and generated files live here; the participant/iOS upload path writes to it via presigned URLs (see the processing pipeline).

Running a subset

mprocs opens a TUI of all services (j/k select, s start, x stop, r restart, a/X stop-all, q quit). To launch just part of the stack:

mprocs --names server,workers

Handy combos:

The agent service

The standalone agent (echo/agent/) runs on :8001. It’s its own uv project:

cd echo/agent
cp .env.sample .env        # set GEMINI_API_KEY
uv sync
uv run uvicorn main:app --host 0.0.0.0 --port 8001 --reload

It comes up automatically in the devcontainer compose; run it by hand when you’re iterating on the agent. See chat & the agent service.

Checking your code

Run echo/check-code.sh before pushing - it’s the repo’s lint/format/type gate. Tests live in echo/server/tests/ and echo/agent/tests/. New work should land with tests, style and docs (see contributing).

Common gotchas


Related

Related

Comments