Self-hosting dembrane
On this page
There is no supported recipe yet for running the whole platform on your own infrastructure. The repository gives you the code, five Dockerfiles and a working local setup. This page says what the platform needs, how to run it on your machine, and where the gaps are.
Read licensing before you run dembrane in production.
What runs#
Five Bun apps, built from dembrane/platform.
| App | What it does |
|---|---|
api |
The HTTP server for the dashboard, the portal and outside agents. |
worker |
Runs queued jobs and schedules: the audio pipeline, analysis, reports, emails. |
media |
An ffmpeg service. It has no database, no bucket credentials and no secrets. |
web |
Serves the built dashboard and portal, and forwards /api to the API. |
migrate |
A one-shot job that runs before every rollout. |
PostgreSQL is the only stateful service the platform itself needs. Jobs, schedules, live updates and rate limits all run on it. There is no Redis, no Directus service, no Python process and no separate agent service.
Run it locally#
You need Bun (the version in dembrane/platform/.bun-version), pnpm and Docker.
cd dembrane/platform
bun run setup # Postgres in docker, dependencies, migrations
bun run dev # API on :8080
bun --env-file=.env.local apps/worker/src/main.ts # worker
bun run check # lint, types, the layer rule, tests
cd dembrane/frontend
pnpm install
pnpm dev # dashboard on :5173, /api proxied to :8080
pnpm participant:dev # portal on :5174
bun run setup copies .env.example to .env.local when it is missing and adds a generated AUTH_SECRET and INVITE_HASH_SECRET. Then it installs dependencies, starts Postgres 16 with pgvector on host port 5433, applies the migrations and adds the default verification topics.
Without Docker, run Postgres 16 with pgvector yourself on port 5432 and run mprocs from dembrane/. It starts the API, the worker, the dashboard and the portal. The one-time commands are in dembrane/platform/README.md.
What local mode does differently#
- Uploaded files and audio go to
.data/filesand.data/audioon disk, and the API serves them itself. This only exists whenAPP_ENVislocalortest. - With no
MEDIA_URL, ffmpeg runs inside the API and the worker, so it must be on yourPATH. - With no
SENDGRID_API_KEY, no email leaves the machine. - Cookies are not marked secure.
- Webhooks may target private addresses.
What a deployment needs#
These requirements come from the code.
| Need | What the code expects |
|---|---|
| PostgreSQL with pgvector | Postgres 16 with pgvector is what the local setup uses. The login that migrates must be able to create the vector extension. Every process connects directly: a transaction-mode pooler breaks the job queue and the live streams. |
| Two database logins | MIGRATION_DATABASE_URL is the owner login for the migrate job. DATABASE_URL is the runtime login. Set APP_DB_ROLE and the migrate job grants that role its data rights. |
| Object storage | Two S3-compatible buckets: files (FILES_S3_*) and audio (STORAGE_S3_*). Outside local and test, the API and the worker refuse to start without both. |
| ffmpeg | Run the media app and set MEDIA_URL, with MEDIA_AUTH=none when it is reachable only inside your cluster. Or put ffmpeg and ffprobe on the PATH of the API and the worker. Their images do not contain ffmpeg. |
| Language models | A Google Cloud project with Vertex AI, and application default credentials. Set LLM_VERTEX_PROJECT. |
SendGrid: SENDGRID_API_KEY, SENDGRID_REGION, EMAIL_FROM, EMAIL_FROM_NAME. |
|
| Secrets | AUTH_SECRET (at least 32 characters) and INVITE_HASH_SECRET (at least 16). |
| Public addresses | API_PUBLIC_URL, DASHBOARD_URL, PORTAL_URL. |
| The frontend | The web app serves the built dembrane/frontend, once with WEB_ROLE=dashboard and once with WEB_ROLE=portal. Set WEB_DIST_DIR and WEB_API_ORIGIN. The web image does the build for you. |
Every setting is on the configuration page.
Images and rollout#
- The five images are built from
dembrane/platform/apps/*/Dockerfile..github/scripts/build-images.sh --loadbuilds them into your local Docker daemon. - Run the migrate job before the API and the worker start on a new version. It applies the schema migrations, installs the queue’s schema, adds the default verification topics and grants the runtime role.
- You can run more than one worker. A schedule runs once across all of them, and the jobs of a worker that dies are resumed by another.
- The API answers
/health(liveness, with the release),/ready(the database) and/ready/worker(a recent worker heartbeat).
Not documented or not supported#
Each of these is the state of the code today, not a plan.
- No recipe runs the whole platform. The compose file starts Postgres only. There is no compose file, Helm chart or installer for all five apps, and the Terraform in
dembrane/infrais for dembrane’s own cloud projects. - There is no self-hosted environment.
APP_ENVmust belocal,test,preview,stagingorprod, and each loads dembrane’s own values. You override them with environment variables. Which one to start from, and the full list of overrides, is not written down. - Models run on Vertex AI only and email on SendGrid only. How to supply Vertex credentials outside Google Cloud is not written down.
- The first user is not described. Sign-up needs a verified email, and email needs SendGrid.
- The first staff member is not described. Staff rights are granted with
bun run staff:access grant <email> --by <staff-email>, which needs an existing staff member, and a fresh database has none. - The frontend expects the web app. Served by the web app, it gets its environment and URLs at run time. Served any other way, it falls back to dembrane’s own URLs for a host it does not know.
- The frontend’s product analytics target is fixed in code and is on for the environments named production and staging. There is no setting to point it elsewhere.
- Some links in the interface point at dembrane’s own pages: privacy statements, legal pages, this documentation.
- The documentation tools of MCP read this site only on dembrane’s own hosts. Elsewhere they need the repository’s
docs/folder beside an API that runs from source. An API image carries no docs.
Comments