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,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Redis Cloud"
|
|
3
|
+
description: "Redis Ltd. managed Redis — Configuration tab endpoints, Connect wizard, rediss://, dynamic vs static endpoints."
|
|
4
|
+
icon: "Zap"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Redis Cloud is Redis Ltd.'s first-party managed service — RESP over TCP/TLS, no separate
|
|
9
|
+
REST layer. `drivers.store.kv` stays `redis`.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
Use `rediss://` (double **s**) with the endpoint from **Configuration** or the **Connect** wizard.
|
|
13
|
+
Prefer **dynamic** endpoints when both are offered.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Find credentials (current console)
|
|
17
|
+
|
|
18
|
+
1. Open Redis Cloud → your **database**.
|
|
19
|
+
2. Open the **Configuration** tab:
|
|
20
|
+
- **Essentials:** endpoint under **Access**
|
|
21
|
+
- **Pro:** endpoint under **General** (expand **Dynamic endpoints** if shown)
|
|
22
|
+
3. Credentials:
|
|
23
|
+
- **Essentials:** **Default user → Configure** → eye icon for password (`default`)
|
|
24
|
+
- **Pro:** **Security** section on Configuration → eye icon for default user password
|
|
25
|
+
4. Or click **Connect** → connection wizard → copy the ready-made client / `redis-cli`
|
|
26
|
+
snippet (fills host, port, user, password).
|
|
27
|
+
|
|
28
|
+
```bash title="process env"
|
|
29
|
+
REDIS_URL=rediss://default:PASSWORD@redis-12345.c1.region.cloud.redislabs.com:12345
|
|
30
|
+
# or dynamic: …@horse-battery-staple-12345.db.redis.io:…
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Port is a **per-database high port**, not always `6379` — copy it from the panel.
|
|
34
|
+
|
|
35
|
+
## Production guidance
|
|
36
|
+
|
|
37
|
+
| Topic | Guidance |
|
|
38
|
+
| ------------- | --------------------------------------------------------------------------------- |
|
|
39
|
+
| TLS | Public endpoints expect TLS → `rediss://` |
|
|
40
|
+
| Endpoint type | **Dynamic** (`*.db.redis.io`) can be redirected later; static `redis-….c…` cannot |
|
|
41
|
+
| Private | Pro private endpoint needs VPC peering / PrivateLink / PSC first |
|
|
42
|
+
| Modules | RediSearch / RedisJSON optional — unused by oke's KV driver |
|
|
43
|
+
| Port | Per-database high port from Configuration — never assume `6379` |
|
|
44
|
+
|
|
45
|
+
Essentials vs Pro panels differ (Access vs General), but **Connect** always opens the
|
|
46
|
+
wizard with a filled client snippet — prefer that when the Configuration layout feels
|
|
47
|
+
unfamiliar after a UI refresh.
|
|
48
|
+
|
|
49
|
+
## Real gotcha — dynamic vs static
|
|
50
|
+
|
|
51
|
+
Apps hard-coded to a **static** `redis-….c…` host cannot follow a later “redirect
|
|
52
|
+
dynamic endpoint” migration. Copy the **dynamic** endpoint from Configuration when both
|
|
53
|
+
exist so you can repoint without code changes.
|
|
54
|
+
|
|
55
|
+
## Troubleshooting
|
|
56
|
+
|
|
57
|
+
<Accordions>
|
|
58
|
+
<Accordion title="NOAUTH / WRONGPASS">
|
|
59
|
+
|
|
60
|
+
Password not in the URL, or default user disabled under RBAC. Format:
|
|
61
|
+
`rediss://default:PASSWORD@host:port`. If default user is off, use a data-access role
|
|
62
|
+
username/password from Access Control.
|
|
63
|
+
|
|
64
|
+
</Accordion>
|
|
65
|
+
<Accordion title="Connection timeout to public endpoint">
|
|
66
|
+
|
|
67
|
+
Pro databases can block public endpoints. Use the private endpoint after peering, or
|
|
68
|
+
re-enable public access in security settings.
|
|
69
|
+
|
|
70
|
+
</Accordion>
|
|
71
|
+
</Accordions>
|
|
72
|
+
|
|
73
|
+
## Learn more
|
|
74
|
+
|
|
75
|
+
- [Redis (image)](/docs/recipes/redis) — self-hosted peer
|
|
76
|
+
- [Store · KV](/docs/elements/store#kv) — TTL physics
|
|
77
|
+
- [Upstash](/docs/providers/upstash) — serverless alternative
|
|
78
|
+
|
|
79
|
+
## Next
|
|
80
|
+
|
|
81
|
+
<Cards>
|
|
82
|
+
<Card
|
|
83
|
+
title="Upstash"
|
|
84
|
+
description="Serverless-friendly alternative."
|
|
85
|
+
href="/docs/providers/upstash"
|
|
86
|
+
/>
|
|
87
|
+
<Card
|
|
88
|
+
title="ElastiCache"
|
|
89
|
+
description="AWS-native alternative."
|
|
90
|
+
href="/docs/providers/elasticache"
|
|
91
|
+
/>
|
|
92
|
+
<Card title="Neon" description="Managed SQL-side pair." href="/docs/providers/neon" />
|
|
93
|
+
</Cards>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Supabase"
|
|
3
|
+
description: "Managed Postgres — Connect button modes, transaction :6543 vs direct :5432, IPv6, free-tier pause."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Supabase wraps Postgres with Auth, Storage, Realtime, and generated APIs. oke only needs
|
|
9
|
+
the Postgres connection underneath — `drivers.store.sql` stays `postgres`.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
Use the dashboard **Connect** button and pick the mode that matches your runtime — Transaction
|
|
13
|
+
pooler for serverless, Direct for migrations. Do not guess ports.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Find credentials (current dashboard)
|
|
17
|
+
|
|
18
|
+
1. Open your project in [supabase.com/dashboard](https://supabase.com/dashboard).
|
|
19
|
+
2. Click **Connect** in the project top bar
|
|
20
|
+
(`?showConnect=true` on the project URL).
|
|
21
|
+
3. Choose a method:
|
|
22
|
+
- **Transaction pooler** — `aws-[region].pooler.supabase.com:6543` (Supavisor
|
|
23
|
+
transaction mode)
|
|
24
|
+
- **Session pooler** — same host, port **5432** (IPv4-friendly persistent clients)
|
|
25
|
+
- **Direct connection** — `db.[project-ref].supabase.co:5432`
|
|
26
|
+
4. Copy the URI; substitute the database password from **Project Settings → Database**
|
|
27
|
+
if the string still shows a placeholder.
|
|
28
|
+
|
|
29
|
+
Alternate path: **Project Settings → Database** → connection string / connection info
|
|
30
|
+
panels (same values as Connect).
|
|
31
|
+
|
|
32
|
+
```bash title="process env"
|
|
33
|
+
# Serverless / many short-lived clients
|
|
34
|
+
DATABASE_URL=postgres://postgres.[ref]:…@aws-0-[region].pooler.supabase.com:6543/postgres
|
|
35
|
+
|
|
36
|
+
# Migrations / pg_dump / long session features
|
|
37
|
+
# Direct (IPv6 by default on Free unless IPv4 add-on):
|
|
38
|
+
# DATABASE_URL=postgres://postgres:…@db.[ref].supabase.co:5432/postgres
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Pooled vs direct
|
|
42
|
+
|
|
43
|
+
| Mode | Host:port | Best for |
|
|
44
|
+
| -------------------------- | --------------------------- | ---------------------------------------------- |
|
|
45
|
+
| Transaction (Supavisor) | `…pooler.supabase.com:6543` | Serverless / edge — default app `DATABASE_URL` |
|
|
46
|
+
| Session (Supavisor) | `…pooler.supabase.com:5432` | Persistent backends on **IPv4-only** networks |
|
|
47
|
+
| Direct | `db.[ref].supabase.co:5432` | Migrations, `pg_dump`, replication |
|
|
48
|
+
| Dedicated PgBouncer (paid) | `db.[ref].supabase.co:6543` | High-performance pooled traffic on paid tiers |
|
|
49
|
+
|
|
50
|
+
**Do not stack** [PgDog](/docs/recipes/pgdog) on top of Supavisor. Transaction mode does
|
|
51
|
+
not support prepared statements — turn them off in the client if you see related errors.
|
|
52
|
+
|
|
53
|
+
**IPv6 gotcha:** Direct (and dedicated pooler) are IPv6 unless you buy the IPv4 add-on.
|
|
54
|
+
IPv4-only app hosts must use the shared pooler hostnames.
|
|
55
|
+
|
|
56
|
+
## pgvector
|
|
57
|
+
|
|
58
|
+
Available on every plan. Enable from the dashboard **Database → Extensions** (or
|
|
59
|
+
`CREATE EXTENSION vector;`). Same `store.index` + `pgvector` driver path as self-hosted
|
|
60
|
+
Postgres.
|
|
61
|
+
|
|
62
|
+
## Free tier — breaks real production
|
|
63
|
+
|
|
64
|
+
| Limit | Free |
|
|
65
|
+
| -------------------------- | ------------------------------------------------------ |
|
|
66
|
+
| Inactivity pause | **7 days** without enough DB activity → project paused |
|
|
67
|
+
| Active projects | **2** |
|
|
68
|
+
| DB size | **500 MB** |
|
|
69
|
+
| Restore window after pause | Finite (platform retention) |
|
|
70
|
+
|
|
71
|
+
Paused projects wake slowly and will fail uptime checks. Paid plans do not auto-pause.
|
|
72
|
+
Do not run user-facing production on Free.
|
|
73
|
+
|
|
74
|
+
## Real gotcha — Connect port mix-ups
|
|
75
|
+
|
|
76
|
+
Since Feb 2025, **6543 is transaction-only** on the shared pooler; session mode is
|
|
77
|
+
**5432** on the pooler host. An old snippet that assumed “6543 = session” will break
|
|
78
|
+
session features or auth in subtle ways — re-copy from **Connect** today.
|
|
79
|
+
|
|
80
|
+
## Troubleshooting
|
|
81
|
+
|
|
82
|
+
<Accordions>
|
|
83
|
+
<Accordion title="Connection refused / timeout to db.[ref].supabase.co">
|
|
84
|
+
|
|
85
|
+
Often IPv4 client → IPv6-only direct endpoint. Switch `DATABASE_URL` to the **Session**
|
|
86
|
+
or **Transaction** pooler host (`pooler.supabase.com`), or enable the IPv4 add-on.
|
|
87
|
+
|
|
88
|
+
</Accordion>
|
|
89
|
+
<Accordion title="Project paused after a quiet week">
|
|
90
|
+
|
|
91
|
+
Free-tier inactivity pause. Restore from the dashboard, then upgrade or keep real DB
|
|
92
|
+
traffic above the pause threshold. Dashboard page views alone may not count.
|
|
93
|
+
|
|
94
|
+
</Accordion>
|
|
95
|
+
</Accordions>
|
|
96
|
+
|
|
97
|
+
## Learn more
|
|
98
|
+
|
|
99
|
+
- [Supabase recipe](/docs/recipes/supabase-docker) — Postgres image only, no platform
|
|
100
|
+
- [Store · Index](/docs/elements/store#index) — `pgvector`
|
|
101
|
+
- [Environment variables](/docs/reference/environment-variables) — `DATABASE_URL`
|
|
102
|
+
|
|
103
|
+
## Next
|
|
104
|
+
|
|
105
|
+
<Cards>
|
|
106
|
+
<Card
|
|
107
|
+
title="Supabase (image)"
|
|
108
|
+
description="Run just the Postgres image."
|
|
109
|
+
href="/docs/recipes/supabase-docker"
|
|
110
|
+
/>
|
|
111
|
+
<Card title="Neon" description="Serverless alternative." href="/docs/providers/neon" />
|
|
112
|
+
<Card
|
|
113
|
+
title="YugabyteDB"
|
|
114
|
+
description="Distributed Apache-2.0 option."
|
|
115
|
+
href="/docs/providers/yugabytedb"
|
|
116
|
+
/>
|
|
117
|
+
</Cards>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Upstash"
|
|
3
|
+
description: "Serverless Redis — Details tab TCP endpoint vs REST URL/token; oke needs rediss:// only."
|
|
4
|
+
icon: "Zap"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Upstash exposes the **same database** two ways: Redis protocol over TLS (TCP) and a
|
|
9
|
+
separate HTTP REST API. oke's `redis` driver speaks **TCP only**.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
From the database **Details** / **Connect** panel, copy the **Redis** / TCP connection
|
|
13
|
+
(`rediss://…`), never `UPSTASH_REDIS_REST_URL` / `UPSTASH_REDIS_REST_TOKEN`.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Find credentials (current console)
|
|
17
|
+
|
|
18
|
+
1. Open [console.upstash.com](https://console.upstash.com) → **Redis** → your database.
|
|
19
|
+
2. On the database page (**Details**):
|
|
20
|
+
- **Endpoint**, **Port**, **Password** (token) for TCP clients
|
|
21
|
+
- Ready-made `redis-cli` / `rediss://` snippets under **Connect** / **Redis**
|
|
22
|
+
3. Ignore the **REST** tab values (`UPSTASH_REDIS_REST_URL`,
|
|
23
|
+
`UPSTASH_REDIS_REST_TOKEN`) for oke — those are for `@upstash/redis` / HTTP only.
|
|
24
|
+
|
|
25
|
+
```bash title="process env"
|
|
26
|
+
REDIS_URL=rediss://default:PASSWORD@usw1-example-12345.upstash.io:6379
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
TLS is mandatory — `redis://` without TLS fails.
|
|
30
|
+
|
|
31
|
+
## Production guidance
|
|
32
|
+
|
|
33
|
+
| Topic | Guidance |
|
|
34
|
+
| ----------- | --------------------------------------------------------------------------- |
|
|
35
|
+
| Transport | TCP `rediss://` for Bun / long-running servers |
|
|
36
|
+
| REST | Edge/serverless SDKs only — **not** wired to `fx.store` |
|
|
37
|
+
| Pricing | Per-request — watch command fan-out in hot KV paths |
|
|
38
|
+
| Eviction | Plan max size / eviction; serverless still has quotas |
|
|
39
|
+
| Consistency | Global replication options are product-specific — confirm region in Details |
|
|
40
|
+
|
|
41
|
+
Do not put [PgDog](/docs/recipes/pgdog)-style thinking on Redis: there is no separate
|
|
42
|
+
“pooled hostname” toggle. Connection count pressure shows up as Upstash plan limits /
|
|
43
|
+
timeouts, not a Neon-style `-pooler` suffix.
|
|
44
|
+
|
|
45
|
+
When debugging, open **Details** and confirm you are reading the **Redis** column, not
|
|
46
|
+
the REST env var block that sits beside it on the same page.
|
|
47
|
+
|
|
48
|
+
## Real gotcha — REST token ≠ Redis password
|
|
49
|
+
|
|
50
|
+
Using `UPSTASH_REDIS_REST_TOKEN` inside a `rediss://` URL (or the reverse) yields
|
|
51
|
+
`WRONGPASS` / `NOAUTH`. REST token and TCP password are different credentials on the
|
|
52
|
+
same console page — copy from the **Redis/TCP** section.
|
|
53
|
+
|
|
54
|
+
## Troubleshooting
|
|
55
|
+
|
|
56
|
+
<Accordions>
|
|
57
|
+
<Accordion title="WRONGPASS invalid or missing auth token">
|
|
58
|
+
|
|
59
|
+
Often a REST token pasted into a TCP client. Re-copy **Password** from Details for
|
|
60
|
+
Redis protocol, build `rediss://:PASSWORD@ENDPOINT:PORT`.
|
|
61
|
+
|
|
62
|
+
</Accordion>
|
|
63
|
+
<Accordion title="NOAUTH Authentication required">
|
|
64
|
+
|
|
65
|
+
Password missing from the URL. ioredis-style URLs need the colon before the password:
|
|
66
|
+
`rediss://:PASSWORD@host:port`.
|
|
67
|
+
|
|
68
|
+
</Accordion>
|
|
69
|
+
</Accordions>
|
|
70
|
+
|
|
71
|
+
## Learn more
|
|
72
|
+
|
|
73
|
+
- [Redis (image)](/docs/recipes/redis)
|
|
74
|
+
- [Redis Cloud](/docs/providers/redis-cloud) — fixed-instance alternative
|
|
75
|
+
- [Store · KV](/docs/elements/store#kv)
|
|
76
|
+
|
|
77
|
+
## Next
|
|
78
|
+
|
|
79
|
+
<Cards>
|
|
80
|
+
<Card
|
|
81
|
+
title="Redis Cloud"
|
|
82
|
+
description="Fixed-instance alternative."
|
|
83
|
+
href="/docs/providers/redis-cloud"
|
|
84
|
+
/>
|
|
85
|
+
<Card
|
|
86
|
+
title="Dragonfly Cloud"
|
|
87
|
+
description="Another managed option."
|
|
88
|
+
href="/docs/providers/dragonfly-cloud"
|
|
89
|
+
/>
|
|
90
|
+
<Card title="Neon" description="Managed SQL-side pair." href="/docs/providers/neon" />
|
|
91
|
+
</Cards>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "YugabyteDB"
|
|
3
|
+
description: "Distributed SQL (YSQL) — Connect → Application, port 5433, CA cert, YSQL vs YCQL."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
YugabyteDB Aeon exposes a Postgres-compatible query layer (**YSQL**). That is the only
|
|
9
|
+
API oke's `postgres` driver targets — not YCQL.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
In **Connect → Connect to your Application**, choose **YSQL** and download the CA cert. Port
|
|
13
|
+
**5433** is the YSQL default — not Postgres's 5432.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
## Find credentials (current console)
|
|
17
|
+
|
|
18
|
+
1. YugabyteDB Aeon → **Clusters** → select the cluster.
|
|
19
|
+
2. Click **Connect**.
|
|
20
|
+
3. Click **Connect to your Application**.
|
|
21
|
+
4. Click **Download CA Cert** and install it where the app can read it.
|
|
22
|
+
5. Select API **YSQL** (not YCQL).
|
|
23
|
+
6. Pick address mode: **Private Address** / **Private Service Endpoint** if VPC-peered;
|
|
24
|
+
**Public Address** only if **Settings → Network Access → Public Access** is enabled
|
|
25
|
+
(not recommended for production).
|
|
26
|
+
7. Copy **Connection String** (or Parameters) into `DATABASE_URL`.
|
|
27
|
+
|
|
28
|
+
```bash title="process env"
|
|
29
|
+
DATABASE_URL=postgresql://admin:…@….aws.yugabyte.cloud:5433/yugabyte?ssl=true&sslmode=verify-full&sslrootcert=/path/to/root.crt
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Also add your app's IPs (or peered VPC) to the cluster **IP allow list** before
|
|
33
|
+
connecting.
|
|
34
|
+
|
|
35
|
+
## Production guidance
|
|
36
|
+
|
|
37
|
+
| Topic | Guidance |
|
|
38
|
+
| ------- | ----------------------------------------------------------------------------- |
|
|
39
|
+
| API | **YSQL only** — YCQL is Cassandra-wire, useless to `postgres` |
|
|
40
|
+
| TLS | `sslmode=verify-full` + downloaded CA |
|
|
41
|
+
| Network | Prefer private / PSE; public access is an explicit opt-in |
|
|
42
|
+
| License | Core is **Apache 2.0** (including once-enterprise features in the core build) |
|
|
43
|
+
|
|
44
|
+
No Neon-style pooled hostname toggle — connection limits and load balancing are
|
|
45
|
+
cluster/VPC topology concerns. Smart drivers want a peered VPC; otherwise they probe
|
|
46
|
+
unreachable nodes first and add latency.
|
|
47
|
+
|
|
48
|
+
## Real gotcha — wrong API tab
|
|
49
|
+
|
|
50
|
+
Copying **YCQL** parameters (port **9042**) into `DATABASE_URL` fails immediately —
|
|
51
|
+
different protocol. Always confirm the Connect dialog shows **YSQL** and port **5433**.
|
|
52
|
+
|
|
53
|
+
## Troubleshooting
|
|
54
|
+
|
|
55
|
+
<Accordions>
|
|
56
|
+
<Accordion title="Connection timed out / could not connect to server">
|
|
57
|
+
|
|
58
|
+
IP allow list or Public Access. Add the client IP under network settings, or use the
|
|
59
|
+
private address from a peered VPC. Public hostname stays dark until Public Access is on.
|
|
60
|
+
|
|
61
|
+
</Accordion>
|
|
62
|
+
<Accordion title="SSL error with verify-full">
|
|
63
|
+
|
|
64
|
+
CA not downloaded or `sslrootcert` path wrong. Re-run **Download CA Cert** from the
|
|
65
|
+
Connect dialog and point the URI at that file.
|
|
66
|
+
|
|
67
|
+
</Accordion>
|
|
68
|
+
</Accordions>
|
|
69
|
+
|
|
70
|
+
## Learn more
|
|
71
|
+
|
|
72
|
+
- [CockroachDB](/docs/providers/cockroachdb) — license / feature comparison
|
|
73
|
+
- [YugabyteDB (self-hosted)](/docs/recipes/yugabytedb) — single-node Docker recipe
|
|
74
|
+
- [Postgres (image)](/docs/recipes/postgres) — driver this backs
|
|
75
|
+
- [Store · SQL](/docs/elements/store#sql) — schema workflows
|
|
76
|
+
|
|
77
|
+
## Next
|
|
78
|
+
|
|
79
|
+
<Cards>
|
|
80
|
+
<Card
|
|
81
|
+
title="CockroachDB"
|
|
82
|
+
description="Compare licensing and features."
|
|
83
|
+
href="/docs/providers/cockroachdb"
|
|
84
|
+
/>
|
|
85
|
+
<Card
|
|
86
|
+
title="Supabase"
|
|
87
|
+
description="Managed single-node option."
|
|
88
|
+
href="/docs/providers/supabase"
|
|
89
|
+
/>
|
|
90
|
+
<Card
|
|
91
|
+
title="Redis Cloud"
|
|
92
|
+
description="Managed Redis-side pair."
|
|
93
|
+
href="/docs/providers/redis-cloud"
|
|
94
|
+
/>
|
|
95
|
+
</Cards>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Caddy"
|
|
3
|
+
description: "Automatic-HTTPS reverse proxy — OKE_PROXY_HOST, Caddyfile, /data certificate volume, single-instance compose."
|
|
4
|
+
icon: "Lock"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Caddy is the simplest TLS path — automatic HTTPS from a generated `Caddyfile`, no
|
|
9
|
+
certificate management by hand. Right choice for a single app instance without `--scale`.
|
|
10
|
+
|
|
11
|
+
<Callout title="The one rule">
|
|
12
|
+
Leave `images.proxy` unset until you need HTTPS at the edge or `--scale app=N`. Once set, `app`
|
|
13
|
+
stops publishing its host port directly — Caddy (or Traefik) does.
|
|
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: "caddy:2-alpine",
|
|
26
|
+
},
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
</Step>
|
|
30
|
+
|
|
31
|
+
<Step>
|
|
32
|
+
### Set the public hostname
|
|
33
|
+
|
|
34
|
+
```bash title="docker/.env.docker"
|
|
35
|
+
OKE_PROXY_HOST=app.example.com
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Unset defaults to `localhost` — Caddy issues a **local** TLS cert instead of Let's Encrypt.
|
|
39
|
+
|
|
40
|
+
</Step>
|
|
41
|
+
|
|
42
|
+
<Step>
|
|
43
|
+
### Include the proxy layer
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
docker compose -f compose.yml -f compose.proxy.yml … up -d
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Generated `Caddyfile`: `{$OKE_PROXY_HOST:localhost} { reverse_proxy app:6530 }`.
|
|
50
|
+
|
|
51
|
+
</Step>
|
|
52
|
+
|
|
53
|
+
</Steps>
|
|
54
|
+
|
|
55
|
+
## Required env
|
|
56
|
+
|
|
57
|
+
| Variable | Required? | Meaning |
|
|
58
|
+
| ----------------------- | ----------- | --------------------------------------------------------------------------- |
|
|
59
|
+
| `OKE_PROXY_HOST` | Recommended | Public hostname for ACME; default `localhost` → local TLS only |
|
|
60
|
+
| `allowedHosts` (config) | Production | Must include the public hostname — see [Security](/docs/reference/security) |
|
|
61
|
+
|
|
62
|
+
Caddy has no separate ACME email env in this recipe (unlike Traefik's
|
|
63
|
+
`OKE_PROXY_ACME_EMAIL`).
|
|
64
|
+
|
|
65
|
+
## Data and backup
|
|
66
|
+
|
|
67
|
+
| Volume | Path | What it stores |
|
|
68
|
+
| -------------- | ----------------------------------------- | ------------------------------- |
|
|
69
|
+
| `proxy-data` | `/data` | ACME certificates, account keys |
|
|
70
|
+
| `proxy-config` | `/config` | Caddy runtime config |
|
|
71
|
+
| Bind mount | `./Caddyfile` → `/etc/caddy/Caddyfile:ro` | Generated site block |
|
|
72
|
+
|
|
73
|
+
**Backup means:** preserve the `proxy-data` named volume (and ideally `proxy-config`) so
|
|
74
|
+
Let's Encrypt rate limits and cert renewals survive recreates. Losing `/data` forces
|
|
75
|
+
re-issuance. The `Caddyfile` is regenerated by `oke docker`.
|
|
76
|
+
|
|
77
|
+
## Production note
|
|
78
|
+
|
|
79
|
+
Caddy has **no** service-discovery story for multiple `app` replicas. Once you run
|
|
80
|
+
`docker compose up --scale app=N`, switch to [Traefik](/docs/recipes/traefik) — it
|
|
81
|
+
discovers replicas from Docker labels instead of a static `reverse_proxy` target.
|
|
82
|
+
|
|
83
|
+
Also set `allowedHosts` to your public hostname before exposing the edge — see
|
|
84
|
+
[Reverse proxy](/docs/deployment/reverse-proxy).
|
|
85
|
+
|
|
86
|
+
## What the recipe configures
|
|
87
|
+
|
|
88
|
+
| Field | Value |
|
|
89
|
+
| -------------- | -------------------------------------------- |
|
|
90
|
+
| Ports | `80` + `443` published; `app` stays internal |
|
|
91
|
+
| Healthcheck | `caddy version`, every 10s, 5 retries |
|
|
92
|
+
| Connection URL | `https://<host>` |
|
|
93
|
+
|
|
94
|
+
## Troubleshooting
|
|
95
|
+
|
|
96
|
+
<Accordions>
|
|
97
|
+
<Accordion title="ACME fails — connection refused / challenge timeout">
|
|
98
|
+
|
|
99
|
+
`OKE_PROXY_HOST` must be a DNS name that resolves to this host on ports 80/443. Localhost
|
|
100
|
+
never gets a public Let's Encrypt cert — that path uses Caddy's local CA. Check firewall
|
|
101
|
+
and that nothing else binds `:80`.
|
|
102
|
+
|
|
103
|
+
</Accordion>
|
|
104
|
+
<Accordion title="Browser trust errors on localhost">
|
|
105
|
+
|
|
106
|
+
Expected with the local CA. Install Caddy's local root for that machine, or set a real
|
|
107
|
+
`OKE_PROXY_HOST` with public DNS when you need a public cert.
|
|
108
|
+
|
|
109
|
+
</Accordion>
|
|
110
|
+
</Accordions>
|
|
111
|
+
|
|
112
|
+
## Learn more
|
|
113
|
+
|
|
114
|
+
- [Reverse proxy](/docs/deployment/reverse-proxy) — Caddy vs Traefik rationale
|
|
115
|
+
- [Docker · Reverse proxy](/docs/deployment/docker#reverse-proxy) — compose layer order
|
|
116
|
+
- [Security](/docs/reference/security) — `allowedHosts`
|
|
117
|
+
|
|
118
|
+
## Next
|
|
119
|
+
|
|
120
|
+
<Cards>
|
|
121
|
+
<Card title="Traefik" description="Multi-replica alternative." href="/docs/recipes/traefik" />
|
|
122
|
+
<Card
|
|
123
|
+
title="PgDog"
|
|
124
|
+
description="Pool Postgres behind the same stack."
|
|
125
|
+
href="/docs/recipes/pgdog"
|
|
126
|
+
/>
|
|
127
|
+
<Card title="Redis" description="The default store.kv image." href="/docs/recipes/redis" />
|
|
128
|
+
</Cards>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "CockroachDB"
|
|
3
|
+
description: "Self-hosted single-node Cockroach — COCKROACH_* env, port 26257, DB Console on :8080, driver stays postgres."
|
|
4
|
+
icon: "Database"
|
|
5
|
+
source: "docs/spec/unified-theory.md"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
CockroachDB speaks Postgres wire closely enough that `drivers.store.sql` stays
|
|
9
|
+
`postgres`. Pin `cockroachdb/cockroach` as `store.sql` and `oke docker` derives a
|
|
10
|
+
single-node compose service — credentials, healthcheck, and `DATABASE_URL`.
|
|
11
|
+
|
|
12
|
+
<Callout title="The one rule">
|
|
13
|
+
The driver id stays `postgres` — vendor choice lives in `images["store.sql"]`, not in
|
|
14
|
+
`drivers.store.sql`. Host maps `:5432` → container `:26257` so local apps keep the usual Postgres
|
|
15
|
+
port.
|
|
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": "cockroachdb/cockroach:v25.2.0", // pin a real tag
|
|
28
|
+
},
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
</Step>
|
|
32
|
+
|
|
33
|
+
<Step>
|
|
34
|
+
### Bring the stack up
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
oke dev --docker
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`oke docker` injects `COCKROACH_USER` / `COCKROACH_PASSWORD` / `COCKROACH_DATABASE`
|
|
41
|
+
from `OKE_STORE_SQL_*`, starts `start-single-node --accept-sql-without-tls`, and
|
|
42
|
+
publishes SQL on host `:5432` plus the DB Console on `:8080`.
|
|
43
|
+
|
|
44
|
+
</Step>
|
|
45
|
+
|
|
46
|
+
<Step>
|
|
47
|
+
### Connect
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
echo "$DATABASE_URL"
|
|
51
|
+
# postgres://oke:…@127.0.0.1:5432/oke?sslmode=require
|
|
52
|
+
```
|
|
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 | → `COCKROACH_USER` (first boot only) |
|
|
63
|
+
| `OKE_STORE_SQL_PASSWORD` | `oke docker` → compose | → `COCKROACH_PASSWORD` |
|
|
64
|
+
| `OKE_STORE_SQL_DB` | `oke docker` → compose | → `COCKROACH_DATABASE` |
|
|
65
|
+
| `DATABASE_URL` | stack env for the app | Includes `sslmode=require` |
|
|
66
|
+
|
|
67
|
+
## Data and backup
|
|
68
|
+
|
|
69
|
+
| Path | What lives there |
|
|
70
|
+
| --------------------------- | --------------------------------------------- |
|
|
71
|
+
| `/cockroach/cockroach-data` | Named volume `store-sql-data` — cluster store |
|
|
72
|
+
|
|
73
|
+
**Backup means:** volume backup of `store-sql-data`, or Cockroach's backup tooling
|
|
74
|
+
against a running node. Losing that volume loses the cluster.
|
|
75
|
+
|
|
76
|
+
## Production note
|
|
77
|
+
|
|
78
|
+
This recipe is a **single-node** cluster — fine for local and small self-hosted apps,
|
|
79
|
+
not multi-region HA. For managed multi-region, use the
|
|
80
|
+
[CockroachDB provider](/docs/providers/cockroachdb). Prefer a pinned tag, not `latest`.
|
|
81
|
+
|
|
82
|
+
## What the recipe configures
|
|
83
|
+
|
|
84
|
+
| Field | Value |
|
|
85
|
+
| -------------- | -------------------------------------------- |
|
|
86
|
+
| Container port | `26257` (host publishes `5432`) |
|
|
87
|
+
| Extra port | `8080` — DB Console |
|
|
88
|
+
| Command | `start-single-node --accept-sql-without-tls` |
|
|
89
|
+
| Healthcheck | `GET /health?ready=1` on `:8080` |
|
|
90
|
+
| Connection URL | `postgres://…?sslmode=require` |
|
|
91
|
+
|
|
92
|
+
## Troubleshooting
|
|
93
|
+
|
|
94
|
+
<Accordions>
|
|
95
|
+
<Accordion title="oke boot: postgres driver needs DATABASE_URL">
|
|
96
|
+
|
|
97
|
+
Re-run `oke dev --docker` so the stack writes `docker/.env.docker`, or export
|
|
98
|
+
`DATABASE_URL` yourself when pointing at a remote Cockroach host.
|
|
99
|
+
|
|
100
|
+
</Accordion>
|
|
101
|
+
<Accordion title="store-sql unhealthy / healthcheck never ready">
|
|
102
|
+
|
|
103
|
+
First boot can take longer than Postgres. Check
|
|
104
|
+
`docker compose … logs store-sql` for SQL ready. Empty `${OKE_STORE_SQL_PASSWORD}`
|
|
105
|
+
in `.env.docker` leaves the init user broken — regenerate the stack env.
|
|
106
|
+
|
|
107
|
+
</Accordion>
|
|
108
|
+
</Accordions>
|
|
109
|
+
|
|
110
|
+
## Learn more
|
|
111
|
+
|
|
112
|
+
- [CockroachDB (provider)](/docs/providers/cockroachdb) — managed Cloud Connect flow
|
|
113
|
+
- [YugabyteDB](/docs/recipes/yugabytedb) — Apache-2.0 self-hosted alternative
|
|
114
|
+
- [Postgres](/docs/recipes/postgres) — default SQL recipe
|
|
115
|
+
- [Store · SQL](/docs/elements/store#sql) — schema push / generate / migrate
|
|
116
|
+
|
|
117
|
+
## Next
|
|
118
|
+
|
|
119
|
+
<Cards>
|
|
120
|
+
<Card
|
|
121
|
+
title="CockroachDB Cloud"
|
|
122
|
+
description="Managed multi-region alternative."
|
|
123
|
+
href="/docs/providers/cockroachdb"
|
|
124
|
+
/>
|
|
125
|
+
<Card title="YugabyteDB" description="Self-hosted YSQL peer." href="/docs/recipes/yugabytedb" />
|
|
126
|
+
<Card title="Postgres" description="The default store.sql image." href="/docs/recipes/postgres" />
|
|
127
|
+
</Cards>
|