okengine 0.9.1 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/manifest.v1.schema.json +9 -1
- package/package.json +3 -3
- package/site/content/docs/console/runs.mdx +10 -0
- package/site/content/docs/console/traces.mdx +4 -0
- package/site/content/docs/elements/ai.mdx +54 -32
- package/site/content/docs/elements/channel.mdx +97 -9
- package/site/content/docs/elements/clock.mdx +1 -0
- package/site/content/docs/elements/flow.mdx +42 -8
- package/site/content/docs/get-started/basic-usage.mdx +5 -1
- package/site/content/docs/get-started/installation.mdx +9 -5
- package/site/content/docs/meta.json +2 -0
- package/site/content/docs/providers/azure-redis.mdx +85 -0
- package/site/content/docs/providers/cockroachdb.mdx +86 -0
- package/site/content/docs/providers/digitalocean-caching.mdx +88 -0
- package/site/content/docs/providers/dragonfly-cloud.mdx +82 -0
- package/site/content/docs/providers/elasticache.mdx +92 -0
- package/site/content/docs/providers/index.mdx +101 -0
- package/site/content/docs/providers/memorystore.mdx +89 -0
- package/site/content/docs/providers/meta.json +20 -0
- package/site/content/docs/providers/neon.mdx +115 -0
- package/site/content/docs/providers/redis-cloud.mdx +93 -0
- package/site/content/docs/providers/supabase.mdx +117 -0
- package/site/content/docs/providers/upstash.mdx +91 -0
- package/site/content/docs/providers/yugabytedb.mdx +95 -0
- package/site/content/docs/recipes/caddy.mdx +128 -0
- package/site/content/docs/recipes/cockroachdb.mdx +127 -0
- package/site/content/docs/recipes/dragonfly.mdx +125 -0
- package/site/content/docs/recipes/index.mdx +146 -0
- package/site/content/docs/recipes/llama-cpp.mdx +153 -0
- package/site/content/docs/recipes/mailpit.mdx +136 -0
- package/site/content/docs/recipes/meilisearch.mdx +139 -0
- package/site/content/docs/recipes/meta.json +31 -0
- package/site/content/docs/recipes/ollama.mdx +142 -0
- package/site/content/docs/recipes/openbao.mdx +141 -0
- package/site/content/docs/recipes/pgdog.mdx +137 -0
- package/site/content/docs/recipes/postgres.mdx +136 -0
- package/site/content/docs/recipes/redis.mdx +130 -0
- package/site/content/docs/recipes/rustfs.mdx +148 -0
- package/site/content/docs/recipes/sglang.mdx +105 -0
- package/site/content/docs/recipes/supabase-docker.mdx +145 -0
- package/site/content/docs/recipes/timescale.mdx +129 -0
- package/site/content/docs/recipes/traefik.mdx +136 -0
- package/site/content/docs/recipes/valkey.mdx +121 -0
- package/site/content/docs/recipes/vllm.mdx +106 -0
- package/site/content/docs/recipes/yugabytedb.mdx +135 -0
- package/site/content/docs/reference/cli.md +42 -6
- package/site/content/docs/reference/configuration.mdx +5 -3
- package/site/content/docs/reference/environment-variables.mdx +12 -12
- package/site/content/docs/reference/fx.mdx +38 -4
- package/src/cli/ai-setup/ai-setup.test.ts +32 -12
- package/src/cli/ai-setup/apply.ts +65 -23
- package/src/cli/ai-setup/catalog.ts +1316 -35
- package/src/cli/ai-setup/detect-ollama.ts +47 -0
- package/src/cli/ai-setup/index.ts +44 -7
- package/src/cli/ai-setup/prompts.ts +430 -486
- package/src/cli/ai-setup/recommend.test.ts +150 -50
- package/src/cli/ai-setup/recommend.ts +118 -101
- package/src/cli/ask-seed.test.ts +68 -0
- package/src/cli/ask-seed.ts +79 -0
- package/src/cli/db-seed-redact.test.ts +25 -0
- package/src/cli/db-seed.ts +36 -7
- package/src/cli/db.test.ts +1 -1
- package/src/cli/db.ts +2 -2
- package/src/cli/dev-app-runner.ts +6 -0
- package/src/cli/dev-controls.test.ts +107 -0
- package/src/cli/dev-controls.ts +354 -0
- package/src/cli/dev-schema-sync.ts +12 -4
- package/src/cli/dev.test.ts +50 -30
- package/src/cli/dev.ts +633 -66
- package/src/cli/docker-cli.test.ts +15 -0
- package/src/cli/drizzle-env.test.ts +40 -6
- package/src/cli/drizzle-env.ts +22 -1
- package/src/cli/ensure-drizzle-config.ts +6 -4
- package/src/cli/hero-meta.test.ts +13 -1
- package/src/cli/hero-meta.ts +28 -6
- package/src/cli/index.ts +5 -0
- package/src/cli/registry.ts +24 -0
- package/src/cli/replay.test.ts +105 -0
- package/src/cli/replay.ts +206 -0
- package/src/cli/start.ts +12 -1
- package/src/compiler/effects-infer.ts +37 -8
- package/src/compiler/extract.test.ts +125 -0
- package/src/compiler/extract.ts +31 -6
- package/src/config/index.ts +3 -3
- package/src/console/server/claim.ts +3 -1
- package/src/console/ui/dist/assets/{index-ClX0ZCe5.js → index-D-9KFce5.js} +2 -2
- package/src/console/ui/dist/assets/panel-overview-CW0CQEc2.js +1 -0
- package/src/console/ui/dist/assets/panel-runs-BxuyDI3x.js +1 -0
- package/src/console/ui/dist/assets/{panel-signals-Dsxdu_AR.js → panel-signals-BXofbj7v.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-hy7O8HOs.js → panel-store-B8mH-arU.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-CBiAe5go.js → panel-traces-DSA-ZWnf.js} +1 -1
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/overview/slo.ts +31 -3
- package/src/console/ui/overview/types.ts +6 -0
- package/src/console/ui/runs/errors.test.ts +53 -0
- package/src/console/ui/runs/errors.ts +88 -0
- package/src/console/ui/runs/index.ts +8 -0
- package/src/console/ui/runs/search.ts +16 -0
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +72 -1
- package/src/docker/ai-model-status.test.ts +101 -0
- package/src/docker/ai-model-status.ts +276 -0
- package/src/docker/compose-health.test.ts +115 -0
- package/src/docker/compose-health.ts +234 -0
- package/src/docker/compose.ts +24 -8
- package/src/docker/derive.ts +35 -9
- package/src/docker/docker.test.ts +304 -12
- package/src/docker/helpers.ts +56 -0
- package/src/docker/index.ts +52 -0
- package/src/docker/ollama-pull.ts +232 -0
- package/src/docker/recipes/cockroach.ts +24 -0
- package/src/docker/recipes/index.ts +32 -0
- package/src/docker/recipes/llama-cpp.ts +273 -0
- package/src/docker/recipes/ollama.ts +19 -23
- package/src/docker/recipes/pgdog.ts +4 -1
- package/src/docker/recipes/postgres.ts +5 -18
- package/src/docker/recipes/sglang.ts +55 -0
- package/src/docker/recipes/supabase.ts +21 -0
- package/src/docker/recipes/timescale.ts +18 -0
- package/src/docker/recipes/vllm.ts +44 -0
- package/src/docker/recipes/yugabyte.ts +23 -0
- package/src/docker/stack-id.test.ts +22 -0
- package/src/docker/stack-id.ts +38 -4
- package/src/docker/types.ts +15 -0
- package/src/drivers/ai-ollama.integration.test.ts +7 -4
- package/src/drivers/signal-engine.ts +10 -0
- package/src/drivers/signal-postgres.ts +24 -2
- package/src/drivers/signal-types.ts +10 -0
- package/src/elements/channel/fallback.test.ts +91 -0
- package/src/elements/channel/hard-bounce.test.ts +82 -0
- package/src/elements/channel/injection.test.ts +153 -0
- package/src/elements/channel/locale-ar.test.ts +102 -0
- package/src/elements/channel/otp-delivery.ts +5 -2
- package/src/elements/channel/receipts-ledger.test.ts +100 -0
- package/src/elements/channel/runtime.ts +24 -1
- package/src/elements/channel/test-helpers.ts +60 -0
- package/src/elements/channel/whatsapp-compliance.test.ts +124 -0
- package/src/elements/store/cache.test.ts +28 -0
- package/src/elements/store/cache.ts +1 -1
- package/src/elements/store/emit-drizzle.ts +43 -9
- package/src/elements/store/runtime.ts +1 -1
- package/src/elements/store/schema-decl.test.ts +2 -0
- package/src/elements/store/schema-decl.ts +15 -0
- package/src/elements/store/seed.ts +1 -1
- package/src/index.ts +1 -0
- package/src/kernel/app.ts +131 -10
- package/src/kernel/boot-bind/signal.ts +6 -2
- package/src/kernel/boot-bind/store.ts +2 -1
- package/src/kernel/boot.test.ts +6 -5
- package/src/kernel/boot.ts +113 -10
- package/src/kernel/compensate.test.ts +131 -0
- package/src/kernel/correlation.test.ts +108 -0
- package/src/kernel/effect-timing.test.ts +82 -0
- package/src/kernel/effects-stamping.test.ts +207 -0
- package/src/kernel/errors.ts +11 -0
- package/src/kernel/flow.ts +38 -0
- package/src/kernel/fx-runs.test.ts +49 -0
- package/src/kernel/fx.test.ts +14 -0
- package/src/kernel/fx.ts +153 -14
- package/src/manifest/sql-resource.ts +41 -0
- package/src/manifest/types.ts +8 -2
- package/src/runs/collect.ts +3 -0
- package/src/runs/export-otlp.ts +64 -0
- package/src/runs/index.ts +16 -0
- package/src/runs/parquet.ts +9 -0
- package/src/runs/types.ts +5 -0
- package/src/runs/window.test.ts +68 -0
- package/src/runs/window.ts +148 -0
- package/src/runtime/boot-warn.test.ts +45 -0
- package/src/runtime/boot-warn.ts +17 -0
- package/src/runtime/dev-request-log.ts +5 -5
- package/src/term.test.ts +95 -10
- package/src/term.ts +369 -14
- package/src/console/ui/dist/assets/panel-overview-DONDzBd2.js +0 -1
- package/src/console/ui/dist/assets/panel-runs-D5zf-D9c.js +0 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Postgres"
|
|
3
|
+
description: "Default store.sql image — POSTGRES_* env, PGDATA path, and when DATABASE_URL points at PgDog instead."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Postgres is the default `store.sql` image in docker and prod. `oke docker` matches
|
|
9
|
+
any image whose reference contains `postgres` or `pgvector` (after more specific
|
|
10
|
+
recipes), then derives env, healthcheck, and connection URL.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
The driver id stays `postgres` no matter which Postgres-wire image you pin — vendor choice lives
|
|
14
|
+
in `images["store.sql"]`, not in `drivers.store.sql`.
|
|
15
|
+
</Callout>
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
<Steps>
|
|
20
|
+
|
|
21
|
+
<Step>
|
|
22
|
+
### Pin the image
|
|
23
|
+
|
|
24
|
+
```typescript title="oke.config.ts"
|
|
25
|
+
images: {
|
|
26
|
+
"store.sql": "postgres:18-alpine", // any Postgres / pgvector image
|
|
27
|
+
},
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
</Step>
|
|
31
|
+
|
|
32
|
+
<Step>
|
|
33
|
+
### Bring the stack up
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
oke dev --docker
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`oke docker` writes `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` into
|
|
40
|
+
`docker/.env.docker` as `${OKE_STORE_SQL_USER}` / `${OKE_STORE_SQL_PASSWORD}` /
|
|
41
|
+
`${OKE_STORE_SQL_DB}` refs — never literal secrets in compose YAML.
|
|
42
|
+
|
|
43
|
+
</Step>
|
|
44
|
+
|
|
45
|
+
<Step>
|
|
46
|
+
### Connect
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# App reads this (also accepts OKE_STORE_SQL_URL)
|
|
50
|
+
echo "$DATABASE_URL"
|
|
51
|
+
# postgres://oke:…@127.0.0.1:5432/oke
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
When PgDog is pinned, `DATABASE_URL` points at `:6432` instead — see
|
|
55
|
+
[PgDog](/docs/recipes/pgdog).
|
|
56
|
+
|
|
57
|
+
</Step>
|
|
58
|
+
|
|
59
|
+
</Steps>
|
|
60
|
+
|
|
61
|
+
## Required env
|
|
62
|
+
|
|
63
|
+
| Variable | Who sets it | Meaning |
|
|
64
|
+
| ------------------------ | ---------------------- | ------------------------------------ |
|
|
65
|
+
| `OKE_STORE_SQL_USER` | `oke docker` → compose | Injected as `POSTGRES_USER` |
|
|
66
|
+
| `OKE_STORE_SQL_PASSWORD` | `oke docker` → compose | Injected as `POSTGRES_PASSWORD` |
|
|
67
|
+
| `OKE_STORE_SQL_DB` | `oke docker` → compose | Injected as `POSTGRES_DB` |
|
|
68
|
+
| `DATABASE_URL` | stack env for the app | What Bun.SQL / Drizzle actually open |
|
|
69
|
+
| `PGDATA` | stack default | `/var/lib/postgresql/data/pgdata` |
|
|
70
|
+
| `POSTGRES_INITDB_ARGS` | stack default | `--data-checksums` |
|
|
71
|
+
|
|
72
|
+
## Data and backup
|
|
73
|
+
|
|
74
|
+
| Path | What lives there |
|
|
75
|
+
| --------------------------------------------- | ---------------------------------------------------- |
|
|
76
|
+
| `$PGDATA` (`/var/lib/postgresql/data/pgdata`) | Cluster data directory |
|
|
77
|
+
| Image `VOLUME` `/var/lib/postgresql/data` | Official image mount — Docker attaches a volume here |
|
|
78
|
+
|
|
79
|
+
The recipe does **not** declare a named compose volume. Persistence rides the image's
|
|
80
|
+
`VOLUME` (anonymous unless you add a named mount in `compose.override.yml`).
|
|
81
|
+
|
|
82
|
+
**Backup means:** `pg_dump` / `pg_dumpall`, or a Docker volume backup of
|
|
83
|
+
`/var/lib/postgresql/data`. Losing that volume loses the cluster.
|
|
84
|
+
|
|
85
|
+
## Production note
|
|
86
|
+
|
|
87
|
+
For multi-replica apps, keep SQL on a shared Postgres — Clock CronStore and durable
|
|
88
|
+
journal need one backend. See [Clock](/docs/elements/clock#what-the-runtime-guarantees) ·
|
|
89
|
+
[Docker](/docs/deployment/docker#share-backing-services).
|
|
90
|
+
|
|
91
|
+
Scale out with [PgDog](/docs/recipes/pgdog) so `N × Bun.SQL pool` does not exhaust
|
|
92
|
+
`max_connections`. Do not also stack a managed provider's pooler on the same URL.
|
|
93
|
+
|
|
94
|
+
## What the recipe configures
|
|
95
|
+
|
|
96
|
+
| Field | Value |
|
|
97
|
+
| -------------- | ---------------------------------------------------- |
|
|
98
|
+
| Container port | `5432` |
|
|
99
|
+
| Healthcheck | `pg_isready -U $POSTGRES_USER`, every 5s, 10 retries |
|
|
100
|
+
| Connection URL | `postgres://user:pass@host:5432/db` |
|
|
101
|
+
|
|
102
|
+
## Troubleshooting
|
|
103
|
+
|
|
104
|
+
<Accordions>
|
|
105
|
+
<Accordion title="oke boot: postgres driver needs DATABASE_URL">
|
|
106
|
+
|
|
107
|
+
The `postgres` driver fails boot when neither `DATABASE_URL` nor `OKE_STORE_SQL_URL` is
|
|
108
|
+
set. Re-run `oke dev --docker` so the stack writes `docker/.env.docker`, or export
|
|
109
|
+
`DATABASE_URL` yourself when pointing at a managed host.
|
|
110
|
+
|
|
111
|
+
</Accordion>
|
|
112
|
+
<Accordion title="pg_isready fails / store-sql unhealthy">
|
|
113
|
+
|
|
114
|
+
Wrong `POSTGRES_USER` or the container is still initializing. Check
|
|
115
|
+
`docker compose … logs store-sql` for `database system is ready to accept connections`.
|
|
116
|
+
|
|
117
|
+
Credential refs must resolve in `.env.docker` — empty `${OKE_STORE_SQL_PASSWORD}` leaves
|
|
118
|
+
Postgres refusing auth.
|
|
119
|
+
|
|
120
|
+
</Accordion>
|
|
121
|
+
</Accordions>
|
|
122
|
+
|
|
123
|
+
## Learn more
|
|
124
|
+
|
|
125
|
+
- [PgDog](/docs/recipes/pgdog) — transaction pooling in front of this recipe
|
|
126
|
+
- [Store · SQL](/docs/elements/store#sql) — schema push / generate / migrate
|
|
127
|
+
- [Environment variables](/docs/reference/environment-variables) — `DATABASE_URL` precedence
|
|
128
|
+
- [Neon](/docs/providers/neon) · [Supabase](/docs/providers/supabase) — managed alternatives
|
|
129
|
+
|
|
130
|
+
## Next
|
|
131
|
+
|
|
132
|
+
<Cards>
|
|
133
|
+
<Card title="PgDog" description="Add pooling in front of Postgres." href="/docs/recipes/pgdog" />
|
|
134
|
+
<Card title="Neon" description="A managed alternative." href="/docs/providers/neon" />
|
|
135
|
+
<Card title="Redis" description="The default store.kv image." href="/docs/recipes/redis" />
|
|
136
|
+
</Cards>
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Redis"
|
|
3
|
+
description: "Default store.kv image — OKE_STORE_KV_PASSWORD, maxmemory policy, ephemeral data, REDIS_URL."
|
|
4
|
+
icon: "Zap"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Redis is the default `store.kv` image in docker and prod. `oke docker` matches image
|
|
9
|
+
references containing `redis` or `keydb` and derives a password-required server — no
|
|
10
|
+
unauthenticated instance.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
The driver id stays `redis` for every Redis-wire image — Redis, Valkey, Dragonfly, or a managed
|
|
14
|
+
provider. Vendor choice lives in `images["store.kv"]`, never in `drivers.store.kv`.
|
|
15
|
+
</Callout>
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
<Steps>
|
|
20
|
+
|
|
21
|
+
<Step>
|
|
22
|
+
### Pin the image
|
|
23
|
+
|
|
24
|
+
```typescript title="oke.config.ts"
|
|
25
|
+
images: {
|
|
26
|
+
"store.kv": "redis:8-alpine",
|
|
27
|
+
},
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
</Step>
|
|
31
|
+
|
|
32
|
+
<Step>
|
|
33
|
+
### Required password
|
|
34
|
+
|
|
35
|
+
```bash title="docker/.env.docker (written by oke docker)"
|
|
36
|
+
OKE_STORE_KV_PASSWORD=…
|
|
37
|
+
REDIS_URL=redis://:…@127.0.0.1:6379
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The recipe runs:
|
|
41
|
+
|
|
42
|
+
`redis-server --requirepass "$OKE_STORE_KV_PASSWORD" --maxmemory … --maxmemory-policy …`
|
|
43
|
+
|
|
44
|
+
</Step>
|
|
45
|
+
|
|
46
|
+
<Step>
|
|
47
|
+
### Optional memory caps
|
|
48
|
+
|
|
49
|
+
| Variable | Default in recipe | Meaning |
|
|
50
|
+
| ------------------------------- | ------------------------------------------------------- | -------- |
|
|
51
|
+
| `OKE_STORE_KV_MAXMEMORY` | `0` (unlimited) in command; stack often sets `256mb` | Max RSS |
|
|
52
|
+
| `OKE_STORE_KV_MAXMEMORY_POLICY` | `noeviction` in command; stack often sets `allkeys-lru` | Eviction |
|
|
53
|
+
|
|
54
|
+
</Step>
|
|
55
|
+
|
|
56
|
+
</Steps>
|
|
57
|
+
|
|
58
|
+
## Required env
|
|
59
|
+
|
|
60
|
+
| Variable | Required? | Meaning |
|
|
61
|
+
| ------------------------------- | ------------- | ------------------------------------------------------------------ |
|
|
62
|
+
| `OKE_STORE_KV_PASSWORD` | **Yes** | `--requirepass` — empty password is not a valid production posture |
|
|
63
|
+
| `REDIS_URL` | **Yes** (app) | What the `redis` driver opens (`OKE_STORE_KV_URL` also works) |
|
|
64
|
+
| `OKE_STORE_KV_MAXMEMORY` | Optional | Cap memory |
|
|
65
|
+
| `OKE_STORE_KV_MAXMEMORY_POLICY` | Optional | Eviction when at cap |
|
|
66
|
+
|
|
67
|
+
## Data and backup
|
|
68
|
+
|
|
69
|
+
The Redis recipe declares **no named volume**. Process memory is the source of truth;
|
|
70
|
+
a container recreate loses keys unless you add persistence yourself
|
|
71
|
+
(`compose.override.yml` + Redis AOF/RDB).
|
|
72
|
+
|
|
73
|
+
**Backup means (default recipe):** treat KV as a cache — rebuild from SQL / files, or
|
|
74
|
+
add an explicit volume + `SAVE`/`BGSAVE` policy before you rely on durability.
|
|
75
|
+
|
|
76
|
+
## Production note
|
|
77
|
+
|
|
78
|
+
<Callout title="License note" type="warn">
|
|
79
|
+
Redis ≥8 is dual-licensed RSALv2 / SSPLv1 / AGPLv3. Those terms restrict offering Redis itself as
|
|
80
|
+
a managed service to third parties — running it for your own app is unaffected. Prefer
|
|
81
|
+
[Valkey](/docs/recipes/valkey) when the managed-service restriction matters.
|
|
82
|
+
</Callout>
|
|
83
|
+
|
|
84
|
+
Multi-replica Gate rate counters and Signal need a **shared** Redis URL — an in-process
|
|
85
|
+
`memory` driver is per instance. Same shared-store idea as
|
|
86
|
+
[Clock](/docs/elements/clock#what-the-runtime-guarantees) for cron exclusivity.
|
|
87
|
+
|
|
88
|
+
## What the recipe configures
|
|
89
|
+
|
|
90
|
+
| Field | Value |
|
|
91
|
+
| -------------- | ---------------------------------------------------- |
|
|
92
|
+
| Container port | `6379` |
|
|
93
|
+
| Healthcheck | `redis-cli -a <password> ping`, every 5s, 10 retries |
|
|
94
|
+
| Connection URL | `redis://:pass@host:6379` |
|
|
95
|
+
|
|
96
|
+
## Troubleshooting
|
|
97
|
+
|
|
98
|
+
<Accordions>
|
|
99
|
+
<Accordion title="oke boot: redis driver needs REDIS_URL">
|
|
100
|
+
|
|
101
|
+
Missing `REDIS_URL` fails boot loudly — never a silent fallback to `memory`. Re-run
|
|
102
|
+
`oke dev --docker` or export `REDIS_URL` when using a managed host. In docker mode the
|
|
103
|
+
message asks whether `oke dev -d` wrote `docker/.env.docker`.
|
|
104
|
+
|
|
105
|
+
</Accordion>
|
|
106
|
+
<Accordion title="NOAUTH Authentication required">
|
|
107
|
+
|
|
108
|
+
`REDIS_URL` is missing the password, or it does not match `OKE_STORE_KV_PASSWORD`.
|
|
109
|
+
Format must be `redis://:PASSWORD@host:6379` (colon before the password, empty username).
|
|
110
|
+
|
|
111
|
+
</Accordion>
|
|
112
|
+
</Accordions>
|
|
113
|
+
|
|
114
|
+
## Learn more
|
|
115
|
+
|
|
116
|
+
- [Store · KV](/docs/elements/store#kv) — TTL physics, per-driver behavior, license table
|
|
117
|
+
- [Valkey](/docs/recipes/valkey) · [Dragonfly](/docs/recipes/dragonfly) — Redis-wire peers
|
|
118
|
+
- [Environment variables](/docs/reference/environment-variables) — `REDIS_URL` precedence
|
|
119
|
+
|
|
120
|
+
## Next
|
|
121
|
+
|
|
122
|
+
<Cards>
|
|
123
|
+
<Card title="Valkey" description="Permissive-licensed alternative." href="/docs/recipes/valkey" />
|
|
124
|
+
<Card title="Redis Cloud" description="Managed Redis." href="/docs/providers/redis-cloud" />
|
|
125
|
+
<Card
|
|
126
|
+
title="Upstash"
|
|
127
|
+
description="Serverless Redis-protocol option."
|
|
128
|
+
href="/docs/providers/upstash"
|
|
129
|
+
/>
|
|
130
|
+
</Cards>
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "RustFS"
|
|
3
|
+
description: "S3-compatible object store — S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY, /data volume, console on :9001."
|
|
4
|
+
icon: "HardDrive"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
RustFS is the default docker `store.files` image — an Apache-2.0 S3-compatible object
|
|
9
|
+
store (MinIO alternative). Driver id stays `s3`; Bun binds `Bun.S3Client` against the
|
|
10
|
+
endpoint.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
Protocol name is `s3` — vendor choice is the image pin (`rustfs/rustfs:…`) plus `S3_ENDPOINT`.
|
|
14
|
+
Never invent a `rustfs` driver id.
|
|
15
|
+
</Callout>
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
<Steps>
|
|
20
|
+
|
|
21
|
+
<Step>
|
|
22
|
+
### Pin driver + image (templates already do)
|
|
23
|
+
|
|
24
|
+
```typescript title="oke.config.ts"
|
|
25
|
+
drivers: {
|
|
26
|
+
store: {
|
|
27
|
+
files: { local: "fs", docker: "s3", test: "memory", prod: "s3" },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
images: {
|
|
31
|
+
"store.files": "rustfs/rustfs:1.0.0-beta.11",
|
|
32
|
+
},
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
</Step>
|
|
36
|
+
|
|
37
|
+
<Step>
|
|
38
|
+
### Credentials and endpoint
|
|
39
|
+
|
|
40
|
+
```bash title="docker/.env.docker (written by oke docker)"
|
|
41
|
+
S3_ACCESS_KEY_ID=…
|
|
42
|
+
S3_SECRET_ACCESS_KEY=…
|
|
43
|
+
S3_BUCKET=oke
|
|
44
|
+
S3_ENDPOINT=http://127.0.0.1:9000
|
|
45
|
+
S3_URL=http://…@127.0.0.1:9000/oke
|
|
46
|
+
S3_REGION=us-east-1
|
|
47
|
+
S3_CONSOLE_URL=http://127.0.0.1:9001
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Recipe maps:
|
|
51
|
+
|
|
52
|
+
- `RUSTFS_ACCESS_KEY=${S3_ACCESS_KEY_ID}`
|
|
53
|
+
- `RUSTFS_SECRET_KEY=${S3_SECRET_ACCESS_KEY}`
|
|
54
|
+
- `RUSTFS_CONSOLE_ENABLE=true`
|
|
55
|
+
- `RUSTFS_ADDRESS=:9000`
|
|
56
|
+
- command: `/data`
|
|
57
|
+
|
|
58
|
+
</Step>
|
|
59
|
+
|
|
60
|
+
<Step>
|
|
61
|
+
### Put an object
|
|
62
|
+
|
|
63
|
+
Any flow using `fx.store` files (`put` / `get`) against the `s3` driver talks to this
|
|
64
|
+
endpoint. Open `S3_CONSOLE_URL` for a browser console on port **9001**.
|
|
65
|
+
|
|
66
|
+
</Step>
|
|
67
|
+
|
|
68
|
+
</Steps>
|
|
69
|
+
|
|
70
|
+
## Required env
|
|
71
|
+
|
|
72
|
+
| Variable | Required? | Meaning |
|
|
73
|
+
| ---------------------- | ----------------- | ------------------------------------------ |
|
|
74
|
+
| `S3_ACCESS_KEY_ID` | **Yes** | Access key → `RUSTFS_ACCESS_KEY` |
|
|
75
|
+
| `S3_SECRET_ACCESS_KEY` | **Yes** | Secret key → `RUSTFS_SECRET_KEY` |
|
|
76
|
+
| `S3_BUCKET` | **Yes** (app) | Bucket name the driver opens |
|
|
77
|
+
| `S3_ENDPOINT` | **Yes** (non-AWS) | Origin `http://host:9000` |
|
|
78
|
+
| `S3_REGION` | Optional | Default `us-east-1` in stack env |
|
|
79
|
+
| `S3_SESSION_TOKEN` | Optional | Temporary creds |
|
|
80
|
+
| `S3_CONSOLE_URL` | Written by stack | UI on `:9001` — not required by the driver |
|
|
81
|
+
| `S3_URL` | Written by stack | Credentialed URL form |
|
|
82
|
+
|
|
83
|
+
## Data and backup
|
|
84
|
+
|
|
85
|
+
| Volume | Path | What it stores |
|
|
86
|
+
| ------------------ | ------- | ------------------------------ |
|
|
87
|
+
| `store-files-data` | `/data` | Object bytes + RustFS metadata |
|
|
88
|
+
|
|
89
|
+
**Backup means:** snapshot that named volume (or `aws s3 sync` against the API).
|
|
90
|
+
Deleting the volume deletes every object.
|
|
91
|
+
|
|
92
|
+
Credentials live in `.env.docker`, not in `/data` — rotate keys without wiping objects.
|
|
93
|
+
Losing both volume and keys means full restore from backup only.
|
|
94
|
+
|
|
95
|
+
## Production note
|
|
96
|
+
|
|
97
|
+
For cloud prod, point the same `s3` driver at real S3 / R2 / GCS interop by changing
|
|
98
|
+
`S3_ENDPOINT` + keys — keep the driver id. Self-hosted RustFS on a single node is a
|
|
99
|
+
durability SPOF: put the `/data` volume on reliable disks and back it up.
|
|
100
|
+
|
|
101
|
+
Do not publish `:9000` / `:9001` on the public internet without TLS and network policy —
|
|
102
|
+
the recipe enables the console for local ops.
|
|
103
|
+
|
|
104
|
+
## What the recipe configures
|
|
105
|
+
|
|
106
|
+
| Field | Value |
|
|
107
|
+
| -------------- | ----------------------------------------------------------------------- |
|
|
108
|
+
| API port | `9000` |
|
|
109
|
+
| Extra port | `9001` → console |
|
|
110
|
+
| Healthcheck | `curl -f http://127.0.0.1:9000/health`, every 5s, 12 retries, 10s start |
|
|
111
|
+
| Connection URL | `http://user:pass@host:9000/bucket` |
|
|
112
|
+
|
|
113
|
+
## Troubleshooting
|
|
114
|
+
|
|
115
|
+
<Accordions>
|
|
116
|
+
<Accordion title="oke boot: redis / meilisearch / S3 URL missing — S3_BUCKET">
|
|
117
|
+
|
|
118
|
+
Files on the `s3` driver need `S3_BUCKET` (or `OKE_STORE_FILES_DB`). Without it the
|
|
119
|
+
facet cannot open. Re-run `oke dev --docker` so stack env fills `S3_*`, or export them
|
|
120
|
+
for a managed bucket.
|
|
121
|
+
|
|
122
|
+
</Accordion>
|
|
123
|
+
<Accordion title="Access Denied / signature errors against :9000">
|
|
124
|
+
|
|
125
|
+
`S3_ACCESS_KEY_ID` / `S3_SECRET_ACCESS_KEY` do not match `RUSTFS_*` inside the
|
|
126
|
+
container, or `S3_ENDPOINT` points at the wrong host/port. Align `.env.docker` with the
|
|
127
|
+
running service; confirm health at `/health` before debugging client signatures.
|
|
128
|
+
|
|
129
|
+
</Accordion>
|
|
130
|
+
</Accordions>
|
|
131
|
+
|
|
132
|
+
## Learn more
|
|
133
|
+
|
|
134
|
+
- [Store · Files](/docs/elements/store#files) — facet API and drivers
|
|
135
|
+
- [Environment variables](/docs/reference/environment-variables) — full `S3_*` map
|
|
136
|
+
- [Installation](/docs/get-started/installation) — docker env cheat sheet
|
|
137
|
+
|
|
138
|
+
## Next
|
|
139
|
+
|
|
140
|
+
<Cards>
|
|
141
|
+
<Card
|
|
142
|
+
title="Mailpit"
|
|
143
|
+
description="SMTP catcher for the same stack."
|
|
144
|
+
href="/docs/recipes/mailpit"
|
|
145
|
+
/>
|
|
146
|
+
<Card title="OpenBao" description="Vault for secrets." href="/docs/recipes/openbao" />
|
|
147
|
+
<Card title="Store" description="Files facet details." href="/docs/elements/store" />
|
|
148
|
+
</Cards>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "SGLang"
|
|
3
|
+
description: "Production-tier self-hosted inference for structured and agent workloads on GPU."
|
|
4
|
+
icon: "Cpu"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
SGLang is for **structured generation and agent-heavy workloads on real GPU
|
|
9
|
+
hardware** when you self-host inference. Prefer a managed provider for most
|
|
10
|
+
production apps. For general multi-user serving, prefer [vLLM](/docs/recipes/vllm).
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
Pin an explicit runtime tag (never `latest`), publish only on loopback, and pick SGLang only when
|
|
14
|
+
structured / agent throughput is the reason you self-host.
|
|
15
|
+
</Callout>
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
<Steps>
|
|
20
|
+
|
|
21
|
+
<Step>
|
|
22
|
+
### Pin driver + image
|
|
23
|
+
|
|
24
|
+
```typescript title="oke.config.ts"
|
|
25
|
+
drivers: {
|
|
26
|
+
ai: { docker: "openai-compatible", prod: "openai-compatible", test: "mock" },
|
|
27
|
+
},
|
|
28
|
+
images: {
|
|
29
|
+
ai: "lmsysorg/sglang:v0.5.16-runtime", // never :latest
|
|
30
|
+
},
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or `oke ai setup --provider sglang --yes`.
|
|
34
|
+
|
|
35
|
+
</Step>
|
|
36
|
+
|
|
37
|
+
<Step>
|
|
38
|
+
### Env + GPU
|
|
39
|
+
|
|
40
|
+
```bash title="docker/.env.docker"
|
|
41
|
+
OKE_AI_URL=http://127.0.0.1:30000/v1
|
|
42
|
+
OKE_AI_MODEL=Qwen/Qwen3-0.6B
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Same NVIDIA reservation pattern as vLLM (`ipc: host` + device reservation).
|
|
46
|
+
|
|
47
|
+
</Step>
|
|
48
|
+
|
|
49
|
+
<Step>
|
|
50
|
+
### Decision matrix
|
|
51
|
+
|
|
52
|
+
| Workload | Recipe |
|
|
53
|
+
| -------------------------------- | -------------------------------------------------------------------------------- |
|
|
54
|
+
| Single-user / dev | [llama.cpp](/docs/recipes/llama-cpp) (default) or [Ollama](/docs/recipes/ollama) |
|
|
55
|
+
| Multi-user GPU serving | [vLLM](/docs/recipes/vllm) |
|
|
56
|
+
| Structured / agent GPU workloads | **SGLang** (this recipe) |
|
|
57
|
+
| Managed cloud | Anthropic / OpenAI / … |
|
|
58
|
+
|
|
59
|
+
</Step>
|
|
60
|
+
|
|
61
|
+
</Steps>
|
|
62
|
+
|
|
63
|
+
## Security
|
|
64
|
+
|
|
65
|
+
| Control | Requirement |
|
|
66
|
+
| ------------ | ---------------------------------------------- |
|
|
67
|
+
| Host publish | `127.0.0.1:30000:30000` only — never `0.0.0.0` |
|
|
68
|
+
| Image pin | Explicit version tag — never `latest` |
|
|
69
|
+
| Model source | Trusted Hugging Face repos / your own weights |
|
|
70
|
+
|
|
71
|
+
## What the recipe configures
|
|
72
|
+
|
|
73
|
+
| Field | Value |
|
|
74
|
+
| -------------- | ----------------------------------------------------- |
|
|
75
|
+
| Container port | `30000` |
|
|
76
|
+
| Host publish | `127.0.0.1:30000:30000` |
|
|
77
|
+
| `ipc` | `host` |
|
|
78
|
+
| GPU | `deploy.resources.reservations.devices` (nvidia, all) |
|
|
79
|
+
| Healthcheck | `GET /health`, long start period for model load |
|
|
80
|
+
| Connection URL | `http://host:30000/v1` |
|
|
81
|
+
|
|
82
|
+
## Troubleshooting
|
|
83
|
+
|
|
84
|
+
<Accordions>
|
|
85
|
+
<Accordion title="GPU not visible / container exits">
|
|
86
|
+
|
|
87
|
+
Install the NVIDIA Container Toolkit. Without a GPU, use
|
|
88
|
+
[llama.cpp](/docs/recipes/llama-cpp) for local smoke tests.
|
|
89
|
+
|
|
90
|
+
</Accordion>
|
|
91
|
+
</Accordions>
|
|
92
|
+
|
|
93
|
+
## Learn more
|
|
94
|
+
|
|
95
|
+
- [vLLM](/docs/recipes/vllm) — general production GPU serving
|
|
96
|
+
- [llama.cpp](/docs/recipes/llama-cpp) — default local AI
|
|
97
|
+
- [AI](/docs/elements/ai) — drivers and `fx.ask`
|
|
98
|
+
|
|
99
|
+
## Next
|
|
100
|
+
|
|
101
|
+
<Cards>
|
|
102
|
+
<Card title="vLLM" description="General multi-user GPU serving." href="/docs/recipes/vllm" />
|
|
103
|
+
<Card title="llama.cpp" description="Default local AI." href="/docs/recipes/llama-cpp" />
|
|
104
|
+
<Card title="AI" description="Prompts and guardrails." href="/docs/elements/ai" />
|
|
105
|
+
</Cards>
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Supabase"
|
|
3
|
+
description: "Pin supabase/postgres as store.sql — extension bundle (pgvector, …) without Auth, Storage, Realtime, or Studio."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Supabase publishes `supabase/postgres` — plain Postgres with a bundled extension set
|
|
9
|
+
(`pgvector`, `pg_graphql`, `pg_cron`, `wrappers`, and more). `oke docker` matches that
|
|
10
|
+
image ahead of the generic Postgres recipe.
|
|
11
|
+
|
|
12
|
+
<Callout title="Not the full Supabase platform">
|
|
13
|
+
This recipe does **not** start GoTrue, PostgREST, Kong, Realtime, Storage, or Studio. Auth, files,
|
|
14
|
+
and realtime delivery are already covered by [Vault](/docs/elements/vault), [Store ·
|
|
15
|
+
files](/docs/elements/store#files), and [Signal](/docs/elements/signal).
|
|
16
|
+
</Callout>
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
<Steps>
|
|
21
|
+
|
|
22
|
+
<Step>
|
|
23
|
+
### Pin the image
|
|
24
|
+
|
|
25
|
+
```typescript title="oke.config.ts"
|
|
26
|
+
images: {
|
|
27
|
+
"store.sql": "supabase/postgres:15.8.1.049", // pin a real tag from Supabase's registry
|
|
28
|
+
},
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
</Step>
|
|
32
|
+
|
|
33
|
+
<Step>
|
|
34
|
+
### Same env shape as Postgres
|
|
35
|
+
|
|
36
|
+
`oke docker` injects the same `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB`
|
|
37
|
+
refs from `OKE_STORE_SQL_*`. Driver id stays `postgres`.
|
|
38
|
+
|
|
39
|
+
</Step>
|
|
40
|
+
|
|
41
|
+
<Step>
|
|
42
|
+
### Use pgvector when you need it
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
drivers: {
|
|
46
|
+
store: {
|
|
47
|
+
index: { local: "memory", docker: "pgvector", prod: "pgvector" },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`CREATE EXTENSION IF NOT EXISTS vector` runs when the `pgvector` index driver opens —
|
|
53
|
+
the extension ships in this image.
|
|
54
|
+
|
|
55
|
+
</Step>
|
|
56
|
+
|
|
57
|
+
</Steps>
|
|
58
|
+
|
|
59
|
+
## Required env
|
|
60
|
+
|
|
61
|
+
| Variable | Meaning |
|
|
62
|
+
| ------------------------ | ----------------------------------------- |
|
|
63
|
+
| `OKE_STORE_SQL_USER` | → `POSTGRES_USER` |
|
|
64
|
+
| `OKE_STORE_SQL_PASSWORD` | → `POSTGRES_PASSWORD` |
|
|
65
|
+
| `OKE_STORE_SQL_DB` | → `POSTGRES_DB` |
|
|
66
|
+
| `DATABASE_URL` | App connection (`postgres://…:5432/…`) |
|
|
67
|
+
| `PGDATA` | Default `/var/lib/postgresql/data/pgdata` |
|
|
68
|
+
|
|
69
|
+
Identical credential contract to [Postgres](/docs/recipes/postgres) — only the image
|
|
70
|
+
(and its extension bundle) differs.
|
|
71
|
+
|
|
72
|
+
## Data and backup
|
|
73
|
+
|
|
74
|
+
| Path | What lives there |
|
|
75
|
+
| ----------------------------------------- | ------------------------------------------ |
|
|
76
|
+
| `$PGDATA` | Cluster data, including extension catalogs |
|
|
77
|
+
| Image `VOLUME` `/var/lib/postgresql/data` | Persistence mount |
|
|
78
|
+
|
|
79
|
+
Same backup story as plain Postgres: `pg_dump` or volume backup of
|
|
80
|
+
`/var/lib/postgresql/data`. Losing that volume loses tables **and** which extensions
|
|
81
|
+
were created.
|
|
82
|
+
|
|
83
|
+
## Production note
|
|
84
|
+
|
|
85
|
+
Want managed Supabase (Auth / Storage / Realtime included)? Use the
|
|
86
|
+
[Supabase provider](/docs/providers/supabase) and set `DATABASE_URL` — do not run this
|
|
87
|
+
image and the cloud project as if they were the same deployment.
|
|
88
|
+
|
|
89
|
+
For self-hosted production, prefer a pinned tag (not `latest`) and the same
|
|
90
|
+
shared-store guidance as [Postgres](/docs/recipes/postgres#production-note). Free-tier
|
|
91
|
+
cloud pausing does not apply to this Docker image — you own uptime.
|
|
92
|
+
|
|
93
|
+
## What the recipe configures
|
|
94
|
+
|
|
95
|
+
| Field | Value |
|
|
96
|
+
| -------------- | ---------------------------------------------------- |
|
|
97
|
+
| Match | `supabase/postgres` before generic `postgres` |
|
|
98
|
+
| Container port | `5432` |
|
|
99
|
+
| Healthcheck | `pg_isready -U $POSTGRES_USER`, every 5s, 10 retries |
|
|
100
|
+
| Connection URL | `postgres://user:pass@host:5432/db` |
|
|
101
|
+
|
|
102
|
+
## Troubleshooting
|
|
103
|
+
|
|
104
|
+
<Accordions>
|
|
105
|
+
<Accordion title='Extension "vector" is not available'>
|
|
106
|
+
|
|
107
|
+
You pinned a plain `postgres:` image, not `supabase/postgres`, or the tag predates the
|
|
108
|
+
bundle. Confirm the image reference contains `supabase/postgres`, then re-derive.
|
|
109
|
+
With the right image, `CREATE EXTENSION vector` succeeds without a separate install.
|
|
110
|
+
|
|
111
|
+
</Accordion>
|
|
112
|
+
<Accordion title="Looking for Studio / the REST API">
|
|
113
|
+
|
|
114
|
+
Those services are not part of this recipe. Use the
|
|
115
|
+
[managed Supabase provider](/docs/providers/supabase) for the full platform, or oke's
|
|
116
|
+
own Vault / Store · files / Signal for those concerns.
|
|
117
|
+
|
|
118
|
+
</Accordion>
|
|
119
|
+
</Accordions>
|
|
120
|
+
|
|
121
|
+
## Learn more
|
|
122
|
+
|
|
123
|
+
- [Supabase (provider)](/docs/providers/supabase) — managed cloud alternative
|
|
124
|
+
- [Postgres](/docs/recipes/postgres) — generic recipe this one takes precedence over
|
|
125
|
+
- [Store · Index](/docs/elements/store#index) — `pgvector`-backed vector search
|
|
126
|
+
|
|
127
|
+
## Next
|
|
128
|
+
|
|
129
|
+
<Cards>
|
|
130
|
+
<Card
|
|
131
|
+
title="Supabase"
|
|
132
|
+
description="Managed cloud, same wire protocol."
|
|
133
|
+
href="/docs/providers/supabase"
|
|
134
|
+
/>
|
|
135
|
+
<Card
|
|
136
|
+
title="PgDog"
|
|
137
|
+
description="Add pooling in front of this recipe too."
|
|
138
|
+
href="/docs/recipes/pgdog"
|
|
139
|
+
/>
|
|
140
|
+
<Card
|
|
141
|
+
title="Postgres"
|
|
142
|
+
description="The plain image this specializes."
|
|
143
|
+
href="/docs/recipes/postgres"
|
|
144
|
+
/>
|
|
145
|
+
</Cards>
|