Running Breno yourself
What Breno is made of, what it needs to run on your own infrastructure, what must be configured, and, honestly, that a packaged private deployment is not available yet.
What it is made of#
| Part | Role |
|---|---|
| API (Go) | The core: every domain, access control, the MCP server, the REST API. |
| Web app (Next.js) | The product's interface. |
| PostgreSQL (with the pgvector extension) | Items, passages, embeddings, memory, audit, and row-level security. |
| Neo4j | The knowledge graph projection. |
| Redis | Rate limits, caches and idempotency keys. Derived state, rebuilt from Postgres. |
| Object storage | Original uploads and exports. |
| Nango (self-hosted) | OAuth and sync for connected sources. |
Background work (ingestion, sync, export, import, clean-up) runs in the API process on every replica, with singletons chosen by leader election, so running more than one replica is safe.
How it can be run#
- Docker Compose for a single node, using the repository's compose files and
.env.exampleas the starting point. - Kubernetes, with manifests in
infra/k8s/(API and web deployments, probes, resource limits, backup jobs), and Prometheus rules and Grafana dashboards ininfra/monitoring/.
What must be configured#
Production refuses to start unless these are right. That is deliberate.
| Variable | Purpose |
|---|---|
APP_ENV | Set to production to turn the checks on. |
JWT_SECRET | Session signing, at least 32 characters. Rotating it signs everyone out. |
CREDENTIAL_ENCRYPTION_KEY (and CREDENTIAL_ENCRYPTION_KEYS for rotation) | Encrypts connector credentials and AI keys at rest. Losing it means re-entering every credential. |
DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME, DB_SSLMODE | PostgreSQL. |
DB_RLS_ENFORCE | Must be on in production, with a database role that is not a superuser. |
NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD | The graph store. |
REDIS_HOST, REDIS_PORT, REDIS_PASSWORD | Redis. |
FRONTEND_URL, API_BASE_URL, NEXT_PUBLIC_API_URL | Where the app and API live, and how links in email are built. |
| A model provider key | At least one provider for embeddings and answers. |
RESEND_API_KEY, EMAIL_FROM | Optional: verification, password reset and invitation email. Without them those emails are only logged. |
The production checks also fail the start if row-level security is not enforced, or the encryption key is missing. Migrations run as a separate step, under a lock, by a privileged job, so the application's own database role does not need to alter the schema.
What leaves#
Exactly one class of traffic leaves your infrastructure: the text sent to your configured model provider for answers and embeddings. The provider client is OpenAI-compatible and the endpoint is configuration, so a model on your own hardware means nothing leaves. If you swap models, re-run the retrieval evaluation, which is in the repository, because quality is yours to own then. See Data flow.
Operating it#
- Backups and restore: see Backups and restore.
- Monitoring: metrics for queue depth, schedule lag, sync duration and failures, with alert rules and a runbook for each alert.
- Tracing: OpenTelemetry end to end, when an endpoint is configured.
- Error tracking: opt-in, and scrubbed of request content.
Sizing#
Scale PostgreSQL memory before anything else: the vector index is the working set that matters. Measured retrieval latency at several corpus sizes is in the repository's docs/baselines/.
Want help?#
If you are planning a private deployment, talk to us. It is better to say what you need now, while the roadmap is still being decided.