okengine 0.9.1 → 0.10.0
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-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 +607 -66
- 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/compiler/extract.ts +3 -3
- 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.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 +117 -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 +8 -3
- 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/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 +111 -1
- 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,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Timescale"
|
|
3
|
+
description: "Self-hosted TimescaleDB — same POSTGRES_* contract as Postgres, hypertables included, driver stays postgres."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
TimescaleDB is Postgres plus hypertables and time-series tooling. Pin a
|
|
9
|
+
`timescale/timescaledb` image as `store.sql` and `oke docker` uses the Timescale
|
|
10
|
+
recipe — same `POSTGRES_*` contract as plain Postgres. Driver id stays `postgres`.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
The driver id stays `postgres` — vendor choice lives in `images["store.sql"]`. Create the
|
|
14
|
+
`timescaledb` extension in SQL when you need hypertables; the image ships it.
|
|
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": "timescale/timescaledb:latest-pg17", // pin a real tag
|
|
27
|
+
},
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
</Step>
|
|
31
|
+
|
|
32
|
+
<Step>
|
|
33
|
+
### Bring the stack up
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
oke dev --docker
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Same credential contract as [Postgres](/docs/recipes/postgres):
|
|
40
|
+
`POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` from `OKE_STORE_SQL_*`.
|
|
41
|
+
|
|
42
|
+
</Step>
|
|
43
|
+
|
|
44
|
+
<Step>
|
|
45
|
+
### Enable the extension when you need it
|
|
46
|
+
|
|
47
|
+
```sql
|
|
48
|
+
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then create hypertables with Timescale's usual DDL — Flows still talk through
|
|
52
|
+
`fx.store` / Drizzle like any other Postgres.
|
|
53
|
+
|
|
54
|
+
</Step>
|
|
55
|
+
|
|
56
|
+
</Steps>
|
|
57
|
+
|
|
58
|
+
## Required env
|
|
59
|
+
|
|
60
|
+
| Variable | Who sets it | Meaning |
|
|
61
|
+
| ------------------------ | ---------------------- | --------------------------------- |
|
|
62
|
+
| `OKE_STORE_SQL_USER` | `oke docker` → compose | → `POSTGRES_USER` |
|
|
63
|
+
| `OKE_STORE_SQL_PASSWORD` | `oke docker` → compose | → `POSTGRES_PASSWORD` |
|
|
64
|
+
| `OKE_STORE_SQL_DB` | `oke docker` → compose | → `POSTGRES_DB` |
|
|
65
|
+
| `DATABASE_URL` | stack env for the app | `postgres://…:5432/…` |
|
|
66
|
+
| `PGDATA` | stack default | `/var/lib/postgresql/data/pgdata` |
|
|
67
|
+
|
|
68
|
+
## Data and backup
|
|
69
|
+
|
|
70
|
+
| Path | What lives there |
|
|
71
|
+
| ----------------------------------------- | ------------------------------------------ |
|
|
72
|
+
| `$PGDATA` | Cluster data, including Timescale catalogs |
|
|
73
|
+
| Image `VOLUME` `/var/lib/postgresql/data` | Persistence mount |
|
|
74
|
+
|
|
75
|
+
Same backup story as plain Postgres: `pg_dump` / volume backup of
|
|
76
|
+
`/var/lib/postgresql/data`. Losing that volume loses tables and extension state.
|
|
77
|
+
|
|
78
|
+
## Production note
|
|
79
|
+
|
|
80
|
+
Pin a concrete tag (image + Postgres major). For multi-replica apps, keep one
|
|
81
|
+
shared SQL backend — see
|
|
82
|
+
[Postgres · Production note](/docs/recipes/postgres#production-note).
|
|
83
|
+
|
|
84
|
+
Managed time-series hosts still use `DATABASE_URL` and
|
|
85
|
+
`drivers.store.sql: "postgres"`.
|
|
86
|
+
|
|
87
|
+
## What the recipe configures
|
|
88
|
+
|
|
89
|
+
| Field | Value |
|
|
90
|
+
| -------------- | --------------------------------------- |
|
|
91
|
+
| Match | `timescale` ahead of generic `postgres` |
|
|
92
|
+
| Container port | `5432` |
|
|
93
|
+
| Healthcheck | `pg_isready -U $POSTGRES_USER` |
|
|
94
|
+
| Connection URL | `postgres://user:pass@host:5432/db` |
|
|
95
|
+
|
|
96
|
+
## Troubleshooting
|
|
97
|
+
|
|
98
|
+
<Accordions>
|
|
99
|
+
<Accordion title='extension "timescaledb" is not available'>
|
|
100
|
+
|
|
101
|
+
You pinned a plain `postgres:` image. Confirm the reference contains `timescale`,
|
|
102
|
+
re-derive, then `CREATE EXTENSION timescaledb`.
|
|
103
|
+
|
|
104
|
+
</Accordion>
|
|
105
|
+
<Accordion title="oke boot: postgres driver needs DATABASE_URL">
|
|
106
|
+
|
|
107
|
+
Same as Postgres — re-run `oke dev --docker` or export `DATABASE_URL` for a remote
|
|
108
|
+
host.
|
|
109
|
+
|
|
110
|
+
</Accordion>
|
|
111
|
+
</Accordions>
|
|
112
|
+
|
|
113
|
+
## Learn more
|
|
114
|
+
|
|
115
|
+
- [Postgres](/docs/recipes/postgres) — generic recipe this specialises
|
|
116
|
+
- [Store · SQL](/docs/elements/store#sql) — schema workflows
|
|
117
|
+
- [Environment variables](/docs/reference/environment-variables) — `DATABASE_URL`
|
|
118
|
+
|
|
119
|
+
## Next
|
|
120
|
+
|
|
121
|
+
<Cards>
|
|
122
|
+
<Card title="Postgres" description="Plain Postgres recipe." href="/docs/recipes/postgres" />
|
|
123
|
+
<Card
|
|
124
|
+
title="Supabase"
|
|
125
|
+
description="Postgres + extension bundle."
|
|
126
|
+
href="/docs/recipes/supabase-docker"
|
|
127
|
+
/>
|
|
128
|
+
<Card title="PgDog" description="Transaction pooling in front." href="/docs/recipes/pgdog" />
|
|
129
|
+
</Cards>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Traefik"
|
|
3
|
+
description: "Docker-label auto-discovery proxy — OKE_PROXY_HOST, OKE_PROXY_ACME_EMAIL, socket-proxy, ACME volume."
|
|
4
|
+
icon: "Lock"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Traefik discovers `app` replicas from Docker labels instead of a static upstream, so
|
|
9
|
+
`docker compose up --scale app=N` load-balances without reconfiguring the proxy.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
Traefik never mounts the raw Docker socket. A filtered `tecnativa/docker-socket-proxy` companion
|
|
13
|
+
exposes only containers / events / ping / version / networks on the internal compose network.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
<Steps>
|
|
19
|
+
|
|
20
|
+
<Step>
|
|
21
|
+
### Pin the proxy
|
|
22
|
+
|
|
23
|
+
```typescript title="oke.config.ts"
|
|
24
|
+
images: {
|
|
25
|
+
proxy: "traefik:v3.3",
|
|
26
|
+
},
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</Step>
|
|
30
|
+
|
|
31
|
+
<Step>
|
|
32
|
+
### Hostname + ACME email
|
|
33
|
+
|
|
34
|
+
```bash title="docker/.env.docker"
|
|
35
|
+
OKE_PROXY_HOST=app.example.com
|
|
36
|
+
OKE_PROXY_ACME_EMAIL=admin@example.com
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`OKE_PROXY_ACME_EMAIL` defaults to `admin@example.com` if unset — set a real mailbox
|
|
40
|
+
before production ACME.
|
|
41
|
+
|
|
42
|
+
</Step>
|
|
43
|
+
|
|
44
|
+
<Step>
|
|
45
|
+
### Scale the app
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
docker compose … up -d --scale app=3
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
App labels: `traefik.http.routers.app.rule=Host(...)`, TLS cert resolver `letsencrypt`,
|
|
52
|
+
load-balancer port `6530`.
|
|
53
|
+
|
|
54
|
+
</Step>
|
|
55
|
+
|
|
56
|
+
</Steps>
|
|
57
|
+
|
|
58
|
+
## Required env
|
|
59
|
+
|
|
60
|
+
| Variable | Required? | Meaning |
|
|
61
|
+
| ----------------------- | -------------------- | ---------------------------------------------- |
|
|
62
|
+
| `OKE_PROXY_HOST` | **Yes** (production) | Host rule + ACME identity; default `localhost` |
|
|
63
|
+
| `OKE_PROXY_ACME_EMAIL` | **Yes** (production) | Let's Encrypt account email |
|
|
64
|
+
| `allowedHosts` (config) | Production | Must include the public hostname |
|
|
65
|
+
|
|
66
|
+
## Data and backup
|
|
67
|
+
|
|
68
|
+
| Volume | Path | What it stores |
|
|
69
|
+
| ------------------- | ------------------------- | ------------------------------------------------- |
|
|
70
|
+
| `proxy-letsencrypt` | `/letsencrypt` | `acme.json` — certificates + ACME account |
|
|
71
|
+
| Socket proxy only | `/var/run/docker.sock:ro` | **Only** the `socket-proxy` companion mounts this |
|
|
72
|
+
|
|
73
|
+
**Backup means:** preserve the `proxy-letsencrypt` volume (especially `acme.json`). Losing
|
|
74
|
+
it forces re-issuance and can hit Let's Encrypt rate limits. The socket-proxy has no
|
|
75
|
+
durable state.
|
|
76
|
+
|
|
77
|
+
## Production note
|
|
78
|
+
|
|
79
|
+
Security posture is intentional: Traefik talks to `tcp://socket-proxy:2375` with a
|
|
80
|
+
filtered API (`CONTAINERS`, `EVENTS`, `PING`, `VERSION`, `NETWORKS` only). Never mount
|
|
81
|
+
raw `docker.sock` on Traefik — see [Reverse proxy](/docs/deployment/reverse-proxy).
|
|
82
|
+
|
|
83
|
+
HTTP entrypoint redirects to `websecure`. For a single instance with no scale plans,
|
|
84
|
+
[Caddy](/docs/recipes/caddy) is simpler (no labels, no companion).
|
|
85
|
+
|
|
86
|
+
## What the recipe configures
|
|
87
|
+
|
|
88
|
+
| Field | Value |
|
|
89
|
+
| ----------- | -------------------------------------------------- |
|
|
90
|
+
| Ports | `80` + `443` |
|
|
91
|
+
| Providers | Docker via socket-proxy, `exposedbydefault=false` |
|
|
92
|
+
| Companion | `tecnativa/docker-socket-proxy:v0.5.0` |
|
|
93
|
+
| Healthcheck | `traefik healthcheck --ping`, every 10s, 5 retries |
|
|
94
|
+
|
|
95
|
+
## Troubleshooting
|
|
96
|
+
|
|
97
|
+
<Accordions>
|
|
98
|
+
<Accordion title="404 / no backend — Traefik cannot see app">
|
|
99
|
+
|
|
100
|
+
Usually `socket-proxy` is down, or `app` lacks Traefik labels. Confirm
|
|
101
|
+
`depends_on: socket-proxy` and that `compose.proxy.yml` merged the app labels.
|
|
102
|
+
|
|
103
|
+
Logs showing Docker provider connection errors point at the socket-proxy, not Traefik
|
|
104
|
+
config syntax.
|
|
105
|
+
|
|
106
|
+
</Accordion>
|
|
107
|
+
<Accordion title="ACME email rejected / rate limited">
|
|
108
|
+
|
|
109
|
+
Replace the default `admin@example.com` with a real `OKE_PROXY_ACME_EMAIL`. If you wiped
|
|
110
|
+
`proxy-letsencrypt`, you may be rate-limited — restore `acme.json` from backup instead of
|
|
111
|
+
re-issuing repeatedly.
|
|
112
|
+
|
|
113
|
+
</Accordion>
|
|
114
|
+
</Accordions>
|
|
115
|
+
|
|
116
|
+
## Learn more
|
|
117
|
+
|
|
118
|
+
- [Reverse proxy](/docs/deployment/reverse-proxy) — Docker-socket-proxy security rationale
|
|
119
|
+
- [Docker · Reverse proxy](/docs/deployment/docker#reverse-proxy) — compose layer order
|
|
120
|
+
- [Security](/docs/reference/security) — `allowedHosts`
|
|
121
|
+
|
|
122
|
+
## Next
|
|
123
|
+
|
|
124
|
+
<Cards>
|
|
125
|
+
<Card title="Caddy" description="Single-instance alternative." href="/docs/recipes/caddy" />
|
|
126
|
+
<Card
|
|
127
|
+
title="PgDog"
|
|
128
|
+
description="Pool Postgres behind the same stack."
|
|
129
|
+
href="/docs/recipes/pgdog"
|
|
130
|
+
/>
|
|
131
|
+
<Card
|
|
132
|
+
title="Redis Cloud"
|
|
133
|
+
description="A managed backing store."
|
|
134
|
+
href="/docs/providers/redis-cloud"
|
|
135
|
+
/>
|
|
136
|
+
</Cards>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Valkey"
|
|
3
|
+
description: "BSD-licensed Redis-wire fork — same redis driver, OKE_STORE_KV_PASSWORD, valkey-server command."
|
|
4
|
+
icon: "Zap"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Valkey is the Linux Foundation's BSD-3-Clause fork of Redis, forked after Redis's 2024
|
|
9
|
+
license change. Same wire protocol — pin the image and nothing in Flow code moves.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
Driver id stays `redis`. Valkey is an image choice, not a driver. `REDIS_URL` and every KV call
|
|
13
|
+
through `fx.store` work exactly as they do against Redis.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
<Steps>
|
|
19
|
+
|
|
20
|
+
<Step>
|
|
21
|
+
### Pin the image
|
|
22
|
+
|
|
23
|
+
```typescript title="oke.config.ts"
|
|
24
|
+
images: {
|
|
25
|
+
"store.kv": "valkey/valkey:8-alpine",
|
|
26
|
+
},
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</Step>
|
|
30
|
+
|
|
31
|
+
<Step>
|
|
32
|
+
### Same password contract as Redis
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
OKE_STORE_KV_PASSWORD=…
|
|
36
|
+
REDIS_URL=redis://:…@127.0.0.1:6379
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Command becomes `valkey-server --requirepass "$OKE_STORE_KV_PASSWORD" …` — healthcheck
|
|
40
|
+
uses `valkey-cli`.
|
|
41
|
+
|
|
42
|
+
</Step>
|
|
43
|
+
|
|
44
|
+
<Step>
|
|
45
|
+
### Optional memory caps
|
|
46
|
+
|
|
47
|
+
Same knobs as Redis: `OKE_STORE_KV_MAXMEMORY`, `OKE_STORE_KV_MAXMEMORY_POLICY`.
|
|
48
|
+
|
|
49
|
+
</Step>
|
|
50
|
+
|
|
51
|
+
</Steps>
|
|
52
|
+
|
|
53
|
+
## Required env
|
|
54
|
+
|
|
55
|
+
| Variable | Required? | Meaning |
|
|
56
|
+
| ------------------------------- | ------------- | --------------------------------------------------- |
|
|
57
|
+
| `OKE_STORE_KV_PASSWORD` | **Yes** | `--requirepass` for `valkey-server` |
|
|
58
|
+
| `REDIS_URL` | **Yes** (app) | Still `redis://` scheme — protocol name, not vendor |
|
|
59
|
+
| `OKE_STORE_KV_MAXMEMORY` | Optional | Memory cap |
|
|
60
|
+
| `OKE_STORE_KV_MAXMEMORY_POLICY` | Optional | Eviction policy |
|
|
61
|
+
|
|
62
|
+
## Data and backup
|
|
63
|
+
|
|
64
|
+
No named volume in the recipe — same ephemeral default as [Redis](/docs/recipes/redis).
|
|
65
|
+
**Backup means:** do not assume durability until you add a volume + persistence config;
|
|
66
|
+
treat the default as a shared cache rebuilt from durable stores.
|
|
67
|
+
|
|
68
|
+
## Production note
|
|
69
|
+
|
|
70
|
+
Choose Valkey when RSAL/SSPL managed-service terms on Redis ≥8 matter to your legal
|
|
71
|
+
posture — BSD-3-Clause carries no such restriction. Feature parity with Redis 7/8 stays
|
|
72
|
+
close since the fork tracks upstream.
|
|
73
|
+
|
|
74
|
+
DigitalOcean's managed product moved onto Valkey after Aiven stepped back from Redis —
|
|
75
|
+
see [DigitalOcean Managed Caching](/docs/providers/digitalocean-caching).
|
|
76
|
+
|
|
77
|
+
## What the recipe configures
|
|
78
|
+
|
|
79
|
+
| Field | Value |
|
|
80
|
+
| -------------- | ------------------------------------------------------------------ |
|
|
81
|
+
| Container port | `6379` |
|
|
82
|
+
| Command | `valkey-server --requirepass … --maxmemory … --maxmemory-policy …` |
|
|
83
|
+
| Healthcheck | `valkey-cli -a <password> ping`, every 5s, 10 retries |
|
|
84
|
+
| Connection URL | `redis://:pass@host:6379` |
|
|
85
|
+
| License | BSD-3-Clause |
|
|
86
|
+
|
|
87
|
+
## Troubleshooting
|
|
88
|
+
|
|
89
|
+
<Accordions>
|
|
90
|
+
<Accordion title="oke boot: redis driver needs REDIS_URL">
|
|
91
|
+
|
|
92
|
+
Same loud failure as Redis — the driver id is still `redis`. Export `REDIS_URL` or let
|
|
93
|
+
`oke dev --docker` write it.
|
|
94
|
+
|
|
95
|
+
</Accordion>
|
|
96
|
+
<Accordion title="Healthcheck uses redis-cli and fails">
|
|
97
|
+
|
|
98
|
+
You still have the Redis recipe matched (image ref contains `redis`). Valkey images must
|
|
99
|
+
match `/valkey/i` so the healthcheck binary is `valkey-cli`. Pin `valkey/valkey:…`
|
|
100
|
+
explicitly.
|
|
101
|
+
|
|
102
|
+
</Accordion>
|
|
103
|
+
</Accordions>
|
|
104
|
+
|
|
105
|
+
## Learn more
|
|
106
|
+
|
|
107
|
+
- [Store · KV](/docs/elements/store#kv) — full Redis-protocol image license table
|
|
108
|
+
- [Redis](/docs/recipes/redis) · [Dragonfly](/docs/recipes/dragonfly) — the other two peers
|
|
109
|
+
- [DigitalOcean Managed Caching](/docs/providers/digitalocean-caching) — managed Valkey
|
|
110
|
+
|
|
111
|
+
## Next
|
|
112
|
+
|
|
113
|
+
<Cards>
|
|
114
|
+
<Card
|
|
115
|
+
title="Dragonfly"
|
|
116
|
+
description="Multi-threaded Redis-wire peer."
|
|
117
|
+
href="/docs/recipes/dragonfly"
|
|
118
|
+
/>
|
|
119
|
+
<Card title="Redis" description="The mature default." href="/docs/recipes/redis" />
|
|
120
|
+
<Card title="Upstash" description="Managed alternative." href="/docs/providers/upstash" />
|
|
121
|
+
</Cards>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "vLLM"
|
|
3
|
+
description: "Production-tier self-hosted inference — OpenAI-compatible GPU serving when you run inference yourself."
|
|
4
|
+
icon: "Cpu"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
vLLM is for **multi-user / production concurrency on real GPU hardware** when
|
|
9
|
+
you choose to self-host inference instead of a managed provider. Driver id stays
|
|
10
|
+
`openai-compatible`. Most apps should prefer Anthropic / OpenAI / … in prod.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
Pin an explicit image tag (never `latest`), publish only on loopback, and treat this as “I run
|
|
14
|
+
production inference myself” — not the default create path.
|
|
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: "vllm/vllm-openai:v0.26.0", // never :latest
|
|
30
|
+
},
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or `oke ai setup --provider vllm --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:8000/v1
|
|
42
|
+
OKE_AI_MODEL=Qwen/Qwen3-0.6B
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The recipe sets `ipc: host` and an NVIDIA device reservation. Host needs the
|
|
46
|
+
NVIDIA Container Toolkit.
|
|
47
|
+
|
|
48
|
+
</Step>
|
|
49
|
+
|
|
50
|
+
<Step>
|
|
51
|
+
### Decide deliberately
|
|
52
|
+
|
|
53
|
+
| Path | When |
|
|
54
|
+
| ------------------------------------ | -------------------------------------------- |
|
|
55
|
+
| Managed provider | Default for most production apps |
|
|
56
|
+
| **vLLM** (this recipe) | Self-hosted multi-user GPU serving |
|
|
57
|
+
| [SGLang](/docs/recipes/sglang) | Self-hosted structured / agent GPU workloads |
|
|
58
|
+
| [llama.cpp](/docs/recipes/llama-cpp) | Single-user / dev (default local) |
|
|
59
|
+
|
|
60
|
+
</Step>
|
|
61
|
+
|
|
62
|
+
</Steps>
|
|
63
|
+
|
|
64
|
+
## Security
|
|
65
|
+
|
|
66
|
+
| Control | Requirement |
|
|
67
|
+
| ------------ | --------------------------------------------- |
|
|
68
|
+
| Host publish | `127.0.0.1:8000:8000` only — never `0.0.0.0` |
|
|
69
|
+
| Image pin | Explicit version tag — never `latest` |
|
|
70
|
+
| Model source | Trusted Hugging Face repos / your own weights |
|
|
71
|
+
|
|
72
|
+
## What the recipe configures
|
|
73
|
+
|
|
74
|
+
| Field | Value |
|
|
75
|
+
| -------------- | ----------------------------------------------------- |
|
|
76
|
+
| Container port | `8000` |
|
|
77
|
+
| Host publish | `127.0.0.1:8000:8000` |
|
|
78
|
+
| `ipc` | `host` |
|
|
79
|
+
| GPU | `deploy.resources.reservations.devices` (nvidia, all) |
|
|
80
|
+
| Healthcheck | `GET /health`, long start period for model load |
|
|
81
|
+
| Connection URL | `http://host:8000/v1` |
|
|
82
|
+
|
|
83
|
+
## Troubleshooting
|
|
84
|
+
|
|
85
|
+
<Accordions>
|
|
86
|
+
<Accordion title="GPU not visible / container exits">
|
|
87
|
+
|
|
88
|
+
Install the NVIDIA Container Toolkit on the host. CPU-only hosts should use
|
|
89
|
+
[llama.cpp](/docs/recipes/llama-cpp) or [Ollama](/docs/recipes/ollama) instead.
|
|
90
|
+
|
|
91
|
+
</Accordion>
|
|
92
|
+
</Accordions>
|
|
93
|
+
|
|
94
|
+
## Learn more
|
|
95
|
+
|
|
96
|
+
- [llama.cpp](/docs/recipes/llama-cpp) — default local AI
|
|
97
|
+
- [SGLang](/docs/recipes/sglang) — structured / agent GPU path
|
|
98
|
+
- [AI](/docs/elements/ai) — drivers and `fx.ask`
|
|
99
|
+
|
|
100
|
+
## Next
|
|
101
|
+
|
|
102
|
+
<Cards>
|
|
103
|
+
<Card title="SGLang" description="Agent / structured GPU serving." href="/docs/recipes/sglang" />
|
|
104
|
+
<Card title="llama.cpp" description="Default local AI." href="/docs/recipes/llama-cpp" />
|
|
105
|
+
<Card title="AI" description="Prompts and guardrails." href="/docs/elements/ai" />
|
|
106
|
+
</Cards>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "YugabyteDB"
|
|
3
|
+
description: "Self-hosted single-node YSQL — YSQL_* env, port 5433, driver stays postgres."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
YugabyteDB's **YSQL** API speaks Postgres wire. Pin `yugabytedb/yugabyte` as
|
|
9
|
+
`store.sql` and `oke docker` derives a single-node `yugabyted` service —
|
|
10
|
+
credentials, healthcheck, and `DATABASE_URL`. Driver id stays `postgres`.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
Use the YSQL API only — never treat YCQL as `store.sql`. Vendor choice lives in
|
|
14
|
+
`images["store.sql"]`; host maps `:5432` → container `:5433`.
|
|
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": "yugabytedb/yugabyte:2025.1.0.0-b100", // pin a real tag
|
|
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` injects `YSQL_USER` / `YSQL_PASSWORD` / `YSQL_DB` from `OKE_STORE_SQL_*`
|
|
40
|
+
(password presence turns authentication on), runs
|
|
41
|
+
`bin/yugabyted start --background=false`, and publishes YSQL on host `:5432`.
|
|
42
|
+
|
|
43
|
+
</Step>
|
|
44
|
+
|
|
45
|
+
<Step>
|
|
46
|
+
### Connect
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
echo "$DATABASE_URL"
|
|
50
|
+
# postgres://oke:…@127.0.0.1:5432/oke
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
First healthy state is slower than plain Postgres — the healthcheck allows a long
|
|
54
|
+
start period.
|
|
55
|
+
|
|
56
|
+
</Step>
|
|
57
|
+
|
|
58
|
+
</Steps>
|
|
59
|
+
|
|
60
|
+
## Required env
|
|
61
|
+
|
|
62
|
+
| Variable | Who sets it | Meaning |
|
|
63
|
+
| ------------------------ | ---------------------- | -------------------------------- |
|
|
64
|
+
| `OKE_STORE_SQL_USER` | `oke docker` → compose | → `YSQL_USER` |
|
|
65
|
+
| `OKE_STORE_SQL_PASSWORD` | `oke docker` → compose | → `YSQL_PASSWORD` (enables auth) |
|
|
66
|
+
| `OKE_STORE_SQL_DB` | `oke docker` → compose | → `YSQL_DB` |
|
|
67
|
+
| `DATABASE_URL` | stack env for the app | Host `:5432` → container `:5433` |
|
|
68
|
+
|
|
69
|
+
## Data and backup
|
|
70
|
+
|
|
71
|
+
| Path | What lives there |
|
|
72
|
+
| ------------------------ | ---------------------------------------------------- |
|
|
73
|
+
| `/home/yugabyte/yb_data` | Named volume `store-sql-data` — `yugabyted` base dir |
|
|
74
|
+
|
|
75
|
+
**Backup means:** volume backup of `store-sql-data`, or Yugabyte's backup tooling.
|
|
76
|
+
Losing that volume loses the universe data.
|
|
77
|
+
|
|
78
|
+
## Production note
|
|
79
|
+
|
|
80
|
+
Single-node `yugabyted` is for local and small self-hosted use. For managed Aeon
|
|
81
|
+
clusters, use the [YugabyteDB provider](/docs/providers/yugabytedb). Pin a concrete
|
|
82
|
+
tag; the image is large and cold-start is slower than Postgres.
|
|
83
|
+
|
|
84
|
+
## What the recipe configures
|
|
85
|
+
|
|
86
|
+
| Field | Value |
|
|
87
|
+
| -------------- | ----------------------------------------------------- |
|
|
88
|
+
| Container port | `5433` (host publishes `5432`) |
|
|
89
|
+
| Command | `bin/yugabyted start --base_dir=… --background=false` |
|
|
90
|
+
| Healthcheck | `ysqlsh … SELECT 1` (90s `start_period`) |
|
|
91
|
+
| Connection URL | `postgres://user:pass@host:5432/db` |
|
|
92
|
+
|
|
93
|
+
## Troubleshooting
|
|
94
|
+
|
|
95
|
+
<Accordions>
|
|
96
|
+
<Accordion title="store-sql unhealthy for a long time">
|
|
97
|
+
|
|
98
|
+
Yugabyte cold-start is slow. Wait through the healthcheck `start_period`, then read
|
|
99
|
+
`docker compose … logs store-sql`.
|
|
100
|
+
|
|
101
|
+
macOS AirPlay on `:7000` can conflict with Yugabyte's master UI — stop AirPlay
|
|
102
|
+
Receiver or remap that port in `compose.override.yml` if you need the UI.
|
|
103
|
+
|
|
104
|
+
</Accordion>
|
|
105
|
+
<Accordion title="password authentication failed">
|
|
106
|
+
|
|
107
|
+
`YSQL_PASSWORD` must match `DATABASE_URL`. Regenerate `docker/.env.docker` with
|
|
108
|
+
`oke dev --docker`. Auth is off only when `YSQL_PASSWORD` is unset — this recipe
|
|
109
|
+
always sets it.
|
|
110
|
+
|
|
111
|
+
</Accordion>
|
|
112
|
+
</Accordions>
|
|
113
|
+
|
|
114
|
+
## Learn more
|
|
115
|
+
|
|
116
|
+
- [YugabyteDB (provider)](/docs/providers/yugabytedb) — managed Aeon Connect flow
|
|
117
|
+
- [CockroachDB](/docs/recipes/cockroachdb) — self-hosted distributed peer
|
|
118
|
+
- [Postgres](/docs/recipes/postgres) — default SQL recipe
|
|
119
|
+
- [Store · SQL](/docs/elements/store#sql) — schema workflows
|
|
120
|
+
|
|
121
|
+
## Next
|
|
122
|
+
|
|
123
|
+
<Cards>
|
|
124
|
+
<Card
|
|
125
|
+
title="YugabyteDB Aeon"
|
|
126
|
+
description="Managed cloud alternative."
|
|
127
|
+
href="/docs/providers/yugabytedb"
|
|
128
|
+
/>
|
|
129
|
+
<Card
|
|
130
|
+
title="CockroachDB"
|
|
131
|
+
description="Self-hosted Cockroach recipe."
|
|
132
|
+
href="/docs/recipes/cockroachdb"
|
|
133
|
+
/>
|
|
134
|
+
<Card title="Postgres" description="The default store.sql image." href="/docs/recipes/postgres" />
|
|
135
|
+
</Cards>
|