page.tsx127 lines · main
1import { DocsShell } from '../../components/shell';
2
3export const metadata = { title: 'self-host' };
4
5export default function SelfHostPage() {
6 return (
7 <DocsShell>
8 <h1 className="font-mono text-2xl tracking-tight">self-host</h1>
9 <p className="mt-2 font-mono text-sm text-[var(--color-text-muted)]">
10 run briven on your own infrastructure. agpl-3.0 for the engine; the cli + client sdks are
11 mit. recommended path is dokploy on hetzner or any vps that runs docker.
12 </p>
13
14 <div className="mt-6 rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-surface)] p-4 font-mono text-xs text-[var(--color-text-muted)]">
15 <strong>self-host status:</strong> the public dokploy + coolify templates ship alongside
16 the public beta. until then this page documents the moving parts so you can plan your
17 deploy; the step-by-step guide lands with the engine&apos;s self-host release.
18 </div>
19
20 <Section title="what you run">
21 <p>three core services + the data plane:</p>
22 <ul className="list-disc pl-5">
23 <li>
24 <code>apps/api</code> — control plane (hono on bun). owns accounts, projects, billing,
25 cli sessions. talks to the meta-db.
26 </li>
27 <li>
28 <code>apps/runtime</code> — function host (deno isolates). receives invokes from the
29 api over a shared-secret-authenticated internal channel.
30 </li>
31 <li>
32 <code>apps/realtime</code> — websocket service for reactive queries. holds a single
33 postgres LISTEN connection and fans out NOTIFYs to subscribers.
34 </li>
35 <li>
36 <code>apps/web</code> — dashboard (next.js 16). marketing + project management ui.
37 </li>
38 </ul>
39 </Section>
40
41 <Section title="data plane">
42 <p>
43 one or more postgres clusters host your customers&apos; per-project schemas. the
44 control plane provisions a schema (<code>proj_&lt;projectId&gt;</code>) on deploy.
45 schema-per-tenant gets you to ~100 tenants per cluster cheaply; graduate to dedicated
46 clusters by tier from there.
47 </p>
48 <p>
49 required postgres extensions: <code>pgvector</code>, <code>pg_cron</code>,{' '}
50 <code>pgmq</code>. the migrations bundled with the api expect these to be available.
51 </p>
52 </Section>
53
54 <Section title="env vars (control plane)">
55 <p>
56 the canonical set lives in <code>apps/api/src/env.ts</code>. every var is prefixed{' '}
57 <code>BRIVEN_</code>. the highlights:
58 </p>
59 <ul className="list-disc pl-5">
60 <li>
61 <code>BRIVEN_DATABASE_URL</code> — control-plane meta-db
62 </li>
63 <li>
64 <code>BRIVEN_DATA_PLANE_URL</code> — superuser dsn the schema-apply path uses to{' '}
65 <code>CREATE SCHEMA</code> per project
66 </li>
67 <li>
68 <code>BRIVEN_REDIS_URL</code> — sessions + queues
69 </li>
70 <li>
71 <code>BRIVEN_BETTER_AUTH_SECRET</code> — session signing
72 </li>
73 <li>
74 <code>BRIVEN_RUNTIME_SHARED_SECRET</code> — the api ↔ runtime ↔ realtime auth token
75 </li>
76 <li>
77 <code>BRIVEN_ENCRYPTION_KEY</code> — aes-256 KEK for customer env vars at rest. fails
78 at boot when unset outside development.
79 </li>
80 <li>
81 <code>BRIVEN_AUDIT_IP_PEPPER</code> — separate from the auth secret so a leaked
82 audit-log column can&apos;t de-anonymise actor ips
83 </li>
84 </ul>
85 </Section>
86
87 <Section title="observability">
88 <p>
89 a turn-key grafana / loki / prometheus / promtail compose project ships under{' '}
90 <code>infra/observability/</code>. wire your services to the same docker network and
91 add the <code>briven_logs=true</code> label to ship structured logs. four starter
92 dashboards cover api requests, runtime invocations, realtime subscriptions, and
93 postgres health.
94 </p>
95 </Section>
96
97 <Section title="licensing">
98 <ul className="list-disc pl-5">
99 <li>
100 <strong>briven engine</strong> (<code>apps/api</code>, <code>apps/runtime</code>,{' '}
101 <code>apps/realtime</code>, <code>apps/web</code>) — agpl-3.0. self-host freely; if
102 you offer it as a service, your modifications need to be public.
103 </li>
104 <li>
105 <strong><code>@briven/cli</code></strong> and the <code>@briven/client-*</code>{' '}
106 packages — mit. embed in any project, no restrictions.
107 </li>
108 <li>
109 commercial licence for the engine is available for cases where agpl is incompatible —
110 contact the team.
111 </li>
112 </ul>
113 </Section>
114 </DocsShell>
115 );
116}
117
118function Section({ title, children }: { title: string; children: React.ReactNode }) {
119 return (
120 <section className="mt-10">
121 <h2 className="font-mono text-lg">{title}</h2>
122 <div className="mt-2 space-y-3 font-mono text-sm text-[var(--color-text-muted)]">
123 {children}
124 </div>
125 </section>
126 );
127}