mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Wire Postgres search backend through chart
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> (cherry picked from commit 86368981635df8b2f050069827b70c7ceea0e5fd) Co-authored-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
This commit is contained in:
parent
5304a9b242
commit
4a771fd08c
@@ -159,7 +159,7 @@ impl Config {
|
||||
"BUZZ_SEARCH_BACKEND={bad:?} (expected `typesense`, `postgres`, or `disabled`)"
|
||||
))
|
||||
})?,
|
||||
Err(_) => buzz_search::SearchBackend::Typesense,
|
||||
Err(_) => buzz_search::SearchBackend::Postgres,
|
||||
};
|
||||
|
||||
let relay_url =
|
||||
@@ -562,17 +562,21 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_backend_defaults_to_typesense() {
|
||||
fn search_backend_defaults_to_postgres() {
|
||||
let _guard = ENV_MUTEX.lock().unwrap();
|
||||
std::env::remove_var("BUZZ_SEARCH_BACKEND");
|
||||
let config = Config::from_env().expect("default config");
|
||||
assert_eq!(config.search_backend, buzz_search::SearchBackend::Typesense);
|
||||
assert_eq!(config.search_backend, buzz_search::SearchBackend::Postgres);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_backend_parses_postgres_and_disabled() {
|
||||
fn search_backend_parses_typesense_postgres_and_disabled() {
|
||||
let _guard = ENV_MUTEX.lock().unwrap();
|
||||
|
||||
std::env::set_var("BUZZ_SEARCH_BACKEND", "typesense");
|
||||
let config = Config::from_env().expect("config");
|
||||
assert_eq!(config.search_backend, buzz_search::SearchBackend::Typesense);
|
||||
|
||||
std::env::set_var("BUZZ_SEARCH_BACKEND", "postgres");
|
||||
let config = Config::from_env().expect("config");
|
||||
assert_eq!(config.search_backend, buzz_search::SearchBackend::Postgres);
|
||||
|
||||
@@ -1250,13 +1250,21 @@ mod tests {
|
||||
.await
|
||||
.expect("pubsub manager"),
|
||||
);
|
||||
let audit = buzz_audit::AuditService::new(pool);
|
||||
let audit = buzz_audit::AuditService::new(pool.clone());
|
||||
let auth = buzz_auth::AuthService::new(config.auth.clone());
|
||||
let search = buzz_search::SearchService::new(buzz_search::SearchConfig {
|
||||
url: config.typesense_url.clone(),
|
||||
api_key: config.typesense_key.clone(),
|
||||
collection: "events".to_string(),
|
||||
});
|
||||
let search = match config.search_backend {
|
||||
buzz_search::SearchBackend::Typesense => {
|
||||
buzz_search::SearchService::new(buzz_search::SearchConfig {
|
||||
url: config.typesense_url.clone(),
|
||||
api_key: config.typesense_key.clone(),
|
||||
collection: "events".to_string(),
|
||||
})
|
||||
}
|
||||
buzz_search::SearchBackend::Postgres => {
|
||||
buzz_search::SearchService::with_postgres(pool.clone())
|
||||
}
|
||||
buzz_search::SearchBackend::Disabled => buzz_search::SearchService::disabled(),
|
||||
};
|
||||
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
|
||||
db.clone(),
|
||||
buzz_workflow::WorkflowConfig::default(),
|
||||
|
||||
@@ -443,13 +443,21 @@ mod tests {
|
||||
.await
|
||||
.ok()?,
|
||||
);
|
||||
let audit = buzz_audit::AuditService::new(pool);
|
||||
let audit = buzz_audit::AuditService::new(pool.clone());
|
||||
let auth = buzz_auth::AuthService::new(config.auth.clone());
|
||||
let search = buzz_search::SearchService::new(buzz_search::SearchConfig {
|
||||
url: config.typesense_url.clone(),
|
||||
api_key: config.typesense_key.clone(),
|
||||
collection: "events".to_string(),
|
||||
});
|
||||
let search = match config.search_backend {
|
||||
buzz_search::SearchBackend::Typesense => {
|
||||
buzz_search::SearchService::new(buzz_search::SearchConfig {
|
||||
url: config.typesense_url.clone(),
|
||||
api_key: config.typesense_key.clone(),
|
||||
collection: "events".to_string(),
|
||||
})
|
||||
}
|
||||
buzz_search::SearchBackend::Postgres => {
|
||||
buzz_search::SearchService::with_postgres(pool.clone())
|
||||
}
|
||||
buzz_search::SearchBackend::Disabled => buzz_search::SearchService::disabled(),
|
||||
};
|
||||
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
|
||||
db.clone(),
|
||||
buzz_workflow::WorkflowConfig::default(),
|
||||
|
||||
@@ -507,13 +507,21 @@ mod tests {
|
||||
.await
|
||||
.expect("pubsub manager"),
|
||||
);
|
||||
let audit = buzz_audit::AuditService::new(pool);
|
||||
let audit = buzz_audit::AuditService::new(pool.clone());
|
||||
let auth = buzz_auth::AuthService::new(config.auth.clone());
|
||||
let search = buzz_search::SearchService::new(buzz_search::SearchConfig {
|
||||
url: config.typesense_url.clone(),
|
||||
api_key: config.typesense_key.clone(),
|
||||
collection: "events".to_string(),
|
||||
});
|
||||
let search = match config.search_backend {
|
||||
buzz_search::SearchBackend::Typesense => {
|
||||
buzz_search::SearchService::new(buzz_search::SearchConfig {
|
||||
url: config.typesense_url.clone(),
|
||||
api_key: config.typesense_key.clone(),
|
||||
collection: "events".to_string(),
|
||||
})
|
||||
}
|
||||
buzz_search::SearchBackend::Postgres => {
|
||||
buzz_search::SearchService::with_postgres(pool.clone())
|
||||
}
|
||||
buzz_search::SearchBackend::Disabled => buzz_search::SearchService::disabled(),
|
||||
};
|
||||
let workflow_engine = std::sync::Arc::new(buzz_workflow::WorkflowEngine::new(
|
||||
db.clone(),
|
||||
buzz_workflow::WorkflowConfig::default(),
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Buzz Helm Chart
|
||||
|
||||
[Buzz](https://github.com/block/buzz) is a Nostr-based messaging platform for human–agent collaboration: a single relay binary serving WebSocket + REST + web UI, backed by PostgreSQL, Redis, Typesense, and S3-compatible object storage.
|
||||
[Buzz](https://github.com/block/buzz) is a Nostr-based messaging platform for human–agent collaboration: a single relay binary serving WebSocket + REST + web UI, backed by PostgreSQL, Redis, and S3-compatible object storage. NIP-50 search defaults to Postgres full-text search, with Typesense available as a fallback backend.
|
||||
|
||||
This chart has two operating profiles selected by values:
|
||||
|
||||
| Profile | When | What you get |
|
||||
|---|---|---|
|
||||
| **Production** (default) | Self-hosted multi-tenant, regulated, or GitOps-managed | External managed Postgres/Redis/Typesense/S3, `secrets.existingSecret:`, no chart-side autogen, HA-capable (`replicaCount ≥ 2`) |
|
||||
| **Quickstart** (eval) | Eval, single-node, one-off demo | In-cluster Postgres + Redis + MinIO + Typesense subcharts/Deployments, chart auto-generates relay + service secrets, single replica |
|
||||
| **Production** (default) | Self-hosted multi-tenant, regulated, or GitOps-managed | External managed Postgres/Redis/S3, Postgres FTS search by default, `secrets.existingSecret:`, no chart-side autogen, HA-capable (`replicaCount ≥ 2`) |
|
||||
| **Quickstart** (eval) | Eval, single-node, one-off demo | In-cluster Postgres + Redis + MinIO, chart auto-generates relay + service secrets, single replica |
|
||||
|
||||
## Quickstart (eval only)
|
||||
|
||||
@@ -18,18 +18,18 @@ helm install buzz oci://ghcr.io/block/buzz/charts/buzz --version 0.1.0 \
|
||||
--set postgresql.enabled=true \
|
||||
--set redis.enabled=true \
|
||||
--set minio.enabled=true \
|
||||
--set typesense.enabled=true \
|
||||
--set relayUrl=wss://buzz.example.com \
|
||||
--set ownerPubkey=<64-char-hex-pubkey>
|
||||
```
|
||||
|
||||
This brings up **everything in-cluster** — Postgres, Redis, MinIO (with its
|
||||
bucket created by a post-install Job), and Typesense — and composes the relay's
|
||||
`BUZZ_S3_ENDPOINT` / `TYPESENSE_URL` plus autogenerated credentials
|
||||
automatically. No external services required. The `quickstart=true` flag is an
|
||||
intent marker surfaced in NOTES.txt; the bundled services are opted in via the
|
||||
four `*.enabled` flags above (see `ci/quickstart-values.yaml` for the exact set
|
||||
CI installs). Eval-only: every bundled service is a single replica with no HA.
|
||||
This brings up the required quickstart dependencies in-cluster — Postgres,
|
||||
Redis, and MinIO (with its bucket created by a post-install Job) — and composes
|
||||
the relay's `BUZZ_S3_ENDPOINT` plus autogenerated credentials automatically.
|
||||
Search defaults to Postgres FTS (`search.backend=postgres`), so no Typesense
|
||||
service is required. The `quickstart=true` flag is an intent marker surfaced in
|
||||
NOTES.txt; the bundled services are opted in via the per-service `*.enabled`
|
||||
flags (see `ci/quickstart-values.yaml` for the exact set CI installs).
|
||||
Eval-only: every bundled service is a single replica with no HA.
|
||||
|
||||
## Production (GitOps)
|
||||
|
||||
@@ -50,7 +50,7 @@ See:
|
||||
| `relayUrl` | Public `wss://` URL clients connect to | Always |
|
||||
| `ownerPubkey` | 64-char lowercase hex Nostr pubkey of the relay operator | When `relay.requireRelayMembership=true` (default) |
|
||||
| `secrets.existingSecret` | Name of pre-created Secret | Production / GitOps |
|
||||
| `externalPostgresql.url` / `externalRedis.url` / `typesense.url` / `s3.endpoint` | External service URLs | Production — when the matching bundled service is disabled (the default) |
|
||||
| `externalPostgresql.url` / `externalRedis.url` / `s3.endpoint` | External service URLs | Production — when the matching bundled service is disabled (the default) |
|
||||
|
||||
The chart fails at `helm install` / `helm template` time with a clear message if any of these are missing or malformed (see `templates/_validate.tpl`).
|
||||
|
||||
@@ -81,17 +81,21 @@ Save these. Losing any of them is data loss. See NOTES.txt printed by `helm inst
|
||||
|
||||
## Honest limitations (v1)
|
||||
|
||||
- **Bundled MinIO + Typesense are eval-only.** The quickstart profile runs an
|
||||
in-cluster MinIO and Typesense (single replica, no HA, `lookup`-autogenerated
|
||||
credentials) so the relay starts with zero external services. Production
|
||||
leaves `minio.enabled` / `typesense.enabled` off and points `s3.endpoint` +
|
||||
`typesense.url` (or `BUZZ_S3_*` / `TYPESENSE_URL` in `existingSecret`) at
|
||||
managed S3-compatible storage and Typesense. The bundled Deployments are not
|
||||
GitOps-safe and are not intended for production traffic.
|
||||
- **Bundled MinIO is eval-only.** The quickstart profile runs an in-cluster MinIO
|
||||
(single replica, no HA, `lookup`-autogenerated credentials) so the relay starts
|
||||
with zero external object-storage dependencies. Production leaves
|
||||
`minio.enabled` off and points `s3.endpoint` (or `BUZZ_S3_*` in
|
||||
`existingSecret`) at managed S3-compatible storage. The bundled Deployment is
|
||||
not GitOps-safe and is not intended for production traffic.
|
||||
- **Typesense is a fallback search backend.** Default search is Postgres FTS
|
||||
(`search.backend=postgres`). To use Typesense instead, set
|
||||
`search.backend=typesense` and provide either `typesense.url`/`apiKey`,
|
||||
`TYPESENSE_URL`/`TYPESENSE_API_KEY` in `secrets.existingSecret`, or
|
||||
`typesense.enabled=true` for eval-only in-cluster Typesense.
|
||||
- **Minimal-mode is not yet supported.** The relay's `BUZZ_PUBSUB=local` /
|
||||
`BUZZ_SEARCH=pg` / filesystem media paths are upstream work in progress —
|
||||
even quickstart currently stands up real Redis, Typesense, and S3 rather than
|
||||
the relay's single-node fallbacks.
|
||||
filesystem media paths are upstream work in progress — even quickstart
|
||||
currently stands up real Redis and S3 rather than the relay's single-node
|
||||
fallbacks.
|
||||
- **OCI publish to GHCR + cosign signing** is a follow-up PR. For now, install the chart from source: `helm install buzz ./deploy/charts/buzz` after cloning the repo.
|
||||
|
||||
## Development
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Quickstart / eval: subcharts on, autogen secrets, single replica.
|
||||
# This is the scenario `ct install` exercises against a kind cluster — it
|
||||
# spins up postgres + redis + minio + typesense in-cluster so the relay can
|
||||
# actually start and pass its S3 conformance probe.
|
||||
# spins up postgres + redis + minio in-cluster so the relay can actually
|
||||
# start and pass its S3 conformance probe. Search defaults to Postgres FTS, so
|
||||
# the quickstart no longer needs in-cluster Typesense unless explicitly testing
|
||||
# search.backend=typesense.
|
||||
quickstart: true
|
||||
postgresql:
|
||||
enabled: true
|
||||
@@ -9,8 +11,6 @@ redis:
|
||||
enabled: true
|
||||
minio:
|
||||
enabled: true
|
||||
typesense:
|
||||
enabled: true
|
||||
relayUrl: wss://buzz.test.local
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000001"
|
||||
relay:
|
||||
|
||||
@@ -37,9 +37,8 @@ spec:
|
||||
externalRedis:
|
||||
url: ""
|
||||
|
||||
typesense:
|
||||
url: "http://typesense.buzz.svc.cluster.local:8108"
|
||||
# apiKey lives in buzz-secrets
|
||||
search:
|
||||
backend: postgres
|
||||
|
||||
s3:
|
||||
endpoint: "https://s3.us-east-1.amazonaws.com"
|
||||
|
||||
@@ -37,9 +37,8 @@ spec:
|
||||
secrets:
|
||||
existingSecret: buzz-secrets
|
||||
|
||||
typesense:
|
||||
url: "http://typesense.buzz.svc.cluster.local:8108"
|
||||
# apiKey lives in buzz-secrets
|
||||
search:
|
||||
backend: postgres
|
||||
|
||||
s3:
|
||||
endpoint: "https://s3.us-east-1.amazonaws.com"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# REDIS_URL — redis://... (required when replicaCount > 1)
|
||||
# TYPESENSE_URL
|
||||
# TYPESENSE_API_KEY
|
||||
# Only required when Helm value search.backend=typesense.
|
||||
# BUZZ_S3_ACCESS_KEY
|
||||
# BUZZ_S3_SECRET_KEY
|
||||
apiVersion: v1
|
||||
|
||||
@@ -26,19 +26,19 @@
|
||||
──────────────────────────────────────────────────────────────────────────────
|
||||
Profile
|
||||
──────────────────────────────────────────────────────────────────────────────
|
||||
{{ if or .Values.postgresql.enabled .Values.redis.enabled .Values.minio.enabled .Values.typesense.enabled }}
|
||||
{{ if or .Values.postgresql.enabled .Values.redis.enabled .Values.minio.enabled (and .Values.typesense.enabled (eq (include "buzz.searchBackend" .) "typesense")) }}
|
||||
⚠ QUICKSTART / EVALUATION PROFILE
|
||||
{{ if .Values.postgresql.enabled }}- In-cluster Postgres subchart (CloudPirates){{ end }}
|
||||
{{ if .Values.redis.enabled }}- In-cluster Redis subchart (CloudPirates){{ end }}
|
||||
{{ if .Values.minio.enabled }}- In-cluster MinIO (eval-only, single replica; bucket "{{ .Values.s3.bucket }}" created by post-install Job){{ end }}
|
||||
{{ if .Values.typesense.enabled }}- In-cluster Typesense (eval-only, single replica){{ end }}
|
||||
{{ if and .Values.typesense.enabled (eq (include "buzz.searchBackend" .) "typesense") }}- In-cluster Typesense (eval-only, single replica){{ end }}
|
||||
- Chart auto-generates secrets via the `lookup` pattern. This is NOT
|
||||
GitOps-safe — secrets will silently rotate under ArgoCD/Flux. For
|
||||
production, see examples/argocd-app.yaml or examples/flux-helmrelease.yaml.
|
||||
|
||||
{{ else }}
|
||||
✓ PRODUCTION PROFILE
|
||||
External Postgres, Redis (if enabled), Typesense, S3.
|
||||
External Postgres, Redis (if enabled), S3; search backend: {{ include "buzz.searchBackend" . }}.
|
||||
{{ if .Values.secrets.existingSecret }}- Secrets sourced from: {{ .Values.secrets.existingSecret }}{{ end }}
|
||||
{{ end }}
|
||||
|
||||
|
||||
@@ -116,6 +116,12 @@ secrets.existingSecret, use that. Otherwise use the chart-managed one.
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Search backend flag. Defaults to Postgres FTS; Typesense remains opt-in fallback. */}}
|
||||
{{- define "buzz.searchBackend" -}}
|
||||
{{- $search := default dict .Values.search -}}
|
||||
{{- default "postgres" $search.backend -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* In-cluster Typesense URL, used when typesense.enabled and url unset. */}}
|
||||
{{- define "buzz.typesenseUrl" -}}
|
||||
{{- if .Values.typesense.url -}}
|
||||
|
||||
@@ -50,9 +50,9 @@ surface at template time regardless of which manifest helm renders first.
|
||||
{{- fail "Postgres source missing: enable postgresql.enabled=true, set externalPostgresql.url, or provide secrets.existingSecret with key DATABASE_URL." -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Typesense source must exist somewhere */}}
|
||||
{{- if not (or .Values.typesense.enabled .Values.typesense.url .Values.secrets.existingSecret) -}}
|
||||
{{- fail "Typesense source missing: enable typesense.enabled=true (quickstart in-cluster), set typesense.url + typesense.apiKey, or provide secrets.existingSecret with keys TYPESENSE_URL + TYPESENSE_API_KEY." -}}
|
||||
{{/* Typesense source is required only when search.backend=typesense. */}}
|
||||
{{- if and (eq (include "buzz.searchBackend" .) "typesense") (not (or .Values.typesense.enabled .Values.typesense.url .Values.secrets.existingSecret)) -}}
|
||||
{{- fail "Typesense source missing for search.backend=typesense: enable typesense.enabled=true (quickstart in-cluster), set typesense.url + typesense.apiKey, or provide secrets.existingSecret with keys TYPESENSE_URL + TYPESENSE_API_KEY." -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* S3 / object-storage source must exist somewhere (relay hard-fails its
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- include "buzz.validate" . -}}
|
||||
{{- $searchBackend := include "buzz.searchBackend" . -}}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -80,6 +81,7 @@ spec:
|
||||
- { name: BUZZ_REQUIRE_RELAY_MEMBERSHIP, value: {{ .Values.relay.requireRelayMembership | quote }} }
|
||||
- { name: BUZZ_ALLOW_NIP_OA_AUTH, value: {{ .Values.relay.allowNipOaAuth | quote }} }
|
||||
- { name: BUZZ_PUBKEY_ALLOWLIST, value: {{ .Values.relay.pubkeyAllowlist | quote }} }
|
||||
- { name: BUZZ_SEARCH_BACKEND, value: {{ $searchBackend | quote }} }
|
||||
{{- if .Values.relay.corsOrigins }}
|
||||
- { name: BUZZ_CORS_ORIGINS, value: {{ join "," .Values.relay.corsOrigins | quote }} }
|
||||
{{- end }}
|
||||
@@ -130,6 +132,7 @@ spec:
|
||||
name: {{ include "buzz.envSecretName" . }}
|
||||
key: REDIS_URL
|
||||
optional: {{ and (eq (.Values.replicaCount | int) 1) (not .Values.redis.enabled) (not .Values.externalRedis.url) }}
|
||||
{{- if eq $searchBackend "typesense" }}
|
||||
- name: TYPESENSE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
@@ -140,6 +143,7 @@ spec:
|
||||
secretKeyRef:
|
||||
name: {{ include "buzz.envSecretName" . }}
|
||||
key: TYPESENSE_API_KEY
|
||||
{{- end }}
|
||||
- name: BUZZ_S3_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
|
||||
@@ -4,7 +4,7 @@ single replica, no TLS, API key from the chart-managed Secret. Production
|
||||
deploys leave typesense.enabled=false and point typesense.url/apiKey (or
|
||||
secrets.existingSecret) at a managed Typesense service.
|
||||
*/ -}}
|
||||
{{- if .Values.typesense.enabled -}}
|
||||
{{- if and .Values.typesense.enabled (eq (include "buzz.searchBackend" .) "typesense") -}}
|
||||
{{- if .Values.secrets.existingSecret -}}
|
||||
{{- fail "typesense.enabled=true (quickstart) is incompatible with secrets.existingSecret. Quickstart autogenerates the Typesense key in the chart-managed Secret; for external Typesense set typesense.enabled=false and provide TYPESENSE_URL/TYPESENSE_API_KEY." -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -73,8 +73,9 @@ data:
|
||||
REDIS_URL: {{ .Values.externalRedis.url | b64enc | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* Typesense — bundled (quickstart) composes URL + autogen key; else
|
||||
pass through external values. */}}
|
||||
{{- /* Typesense — only when search.backend=typesense. Bundled quickstart
|
||||
composes URL + autogen key; else pass through external values. */}}
|
||||
{{- if eq (include "buzz.searchBackend" .) "typesense" }}
|
||||
{{- if .Values.typesense.enabled }}
|
||||
{{- $tsKey := "" }}
|
||||
{{- if (index $existingData "TYPESENSE_API_KEY") }}
|
||||
@@ -94,6 +95,7 @@ data:
|
||||
TYPESENSE_API_KEY: {{ .Values.typesense.apiKey | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- /* S3 creds — bundled MinIO (quickstart) autogenerates; else pass
|
||||
through external values. */}}
|
||||
|
||||
@@ -9,8 +9,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -29,8 +27,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -47,8 +43,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -68,8 +62,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
suite: quickstart bundled services
|
||||
# The dev quickstart must stand up MinIO + Typesense in-cluster so the relay's
|
||||
# startup S3 conformance probe passes with zero external dependencies.
|
||||
# The dev quickstart must stand up MinIO in-cluster so the relay's startup S3
|
||||
# conformance probe passes. Typesense is only bundled when search.backend=typesense.
|
||||
templates:
|
||||
- templates/quickstart-minio.yaml
|
||||
- templates/quickstart-minio-init.yaml
|
||||
@@ -17,6 +17,7 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
redis.enabled: true
|
||||
search.backend: typesense
|
||||
typesense.enabled: true
|
||||
minio.enabled: true
|
||||
asserts:
|
||||
@@ -40,6 +41,7 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
redis.enabled: true
|
||||
search.backend: typesense
|
||||
typesense.enabled: true
|
||||
minio.enabled: true
|
||||
asserts:
|
||||
@@ -58,6 +60,7 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
redis.enabled: true
|
||||
search.backend: typesense
|
||||
typesense.enabled: true
|
||||
minio.enabled: true
|
||||
asserts:
|
||||
@@ -76,6 +79,7 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
redis.enabled: true
|
||||
search.backend: typesense
|
||||
typesense.enabled: true
|
||||
minio.enabled: true
|
||||
asserts:
|
||||
@@ -103,6 +107,7 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
redis.enabled: true
|
||||
search.backend: typesense
|
||||
typesense.enabled: true
|
||||
minio.enabled: true
|
||||
asserts:
|
||||
|
||||
@@ -10,8 +10,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
minio.enabled: true
|
||||
secrets.existingSecret: "buzz-secrets"
|
||||
asserts:
|
||||
@@ -28,6 +26,7 @@ tests:
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
search.backend: typesense
|
||||
typesense.enabled: true
|
||||
secrets.existingSecret: "buzz-secrets"
|
||||
asserts:
|
||||
|
||||
@@ -8,14 +8,12 @@ templates:
|
||||
- templates/service.yaml
|
||||
- templates/pvc-git.yaml
|
||||
tests:
|
||||
- it: renders cleanly in production profile (external pg/redis/typesense)
|
||||
- it: renders cleanly in production profile (external pg/redis/s3, postgres search)
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
externalRedis.url: redis://h:6379
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -39,8 +37,6 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
externalRedis.url: redis://h:6379
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -55,3 +51,56 @@ tests:
|
||||
path: spec.accessModes[0]
|
||||
value: ReadWriteMany
|
||||
template: templates/pvc-git.yaml
|
||||
|
||||
- it: postgres backend does not require a Typesense source
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BUZZ_SEARCH_BACKEND
|
||||
value: "postgres"
|
||||
template: templates/deployment.yaml
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: TYPESENSE_URL
|
||||
template: templates/deployment.yaml
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: TYPESENSE_API_KEY
|
||||
template: templates/deployment.yaml
|
||||
|
||||
- it: disabled backend does not require a Typesense source
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
search.backend: disabled
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BUZZ_SEARCH_BACKEND
|
||||
value: "disabled"
|
||||
template: templates/deployment.yaml
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: TYPESENSE_URL
|
||||
template: templates/deployment.yaml
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: TYPESENSE_API_KEY
|
||||
template: templates/deployment.yaml
|
||||
|
||||
@@ -8,8 +8,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -31,8 +29,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -47,8 +43,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -70,8 +64,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -93,8 +85,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
@@ -106,6 +96,47 @@ tests:
|
||||
value: "true"
|
||||
template: templates/deployment.yaml
|
||||
|
||||
- it: postgres search Secret omits Typesense keys
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
asserts:
|
||||
- notExists:
|
||||
path: data.TYPESENSE_URL
|
||||
template: templates/secret-chart.yaml
|
||||
- notExists:
|
||||
path: data.TYPESENSE_API_KEY
|
||||
template: templates/secret-chart.yaml
|
||||
|
||||
- it: typesense search Secret includes Typesense keys
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
search.backend: typesense
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
asserts:
|
||||
- equal:
|
||||
path: data.TYPESENSE_URL
|
||||
decodeBase64: true
|
||||
value: http://ts:8108
|
||||
template: templates/secret-chart.yaml
|
||||
- equal:
|
||||
path: data.TYPESENSE_API_KEY
|
||||
decodeBase64: true
|
||||
value: k
|
||||
template: templates/secret-chart.yaml
|
||||
|
||||
- it: quickstart composes DATABASE_URL/REDIS_URL at the actual subchart Service hosts
|
||||
release:
|
||||
name: rel
|
||||
@@ -114,8 +145,6 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
postgresql.enabled: true
|
||||
redis.enabled: true
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
s3.endpoint: http://minio:9000
|
||||
s3.accessKey: a
|
||||
s3.secretKey: s
|
||||
|
||||
@@ -7,8 +7,6 @@ tests:
|
||||
relayUrl: ""
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: "relayUrl is required: set --set relayUrl=wss://your.domain"
|
||||
@@ -18,8 +16,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: ""
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "ownerPubkey is required when relay.requireRelayMembership=true"
|
||||
@@ -29,8 +25,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "NOTAHEX"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "ownerPubkey: Does not match pattern"
|
||||
@@ -40,8 +34,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
replicaCount: 3
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
@@ -53,8 +45,6 @@ tests:
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
externalRedis.url: redis://h:6379
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
replicaCount: 3
|
||||
persistence.git.accessMode: ReadWriteOnce
|
||||
asserts:
|
||||
@@ -66,8 +56,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
ingress.enabled: true
|
||||
httproute.enabled: true
|
||||
asserts:
|
||||
@@ -78,17 +66,16 @@ tests:
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "Postgres source missing"
|
||||
|
||||
- it: fails when Typesense source is missing
|
||||
- it: fails when Typesense source is missing for typesense backend
|
||||
set:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
search.backend: typesense
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "Typesense source missing"
|
||||
@@ -98,8 +85,6 @@ tests:
|
||||
relayUrl: wss://buzz.example.com
|
||||
ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
externalPostgresql.url: postgres://u:p@h:5432/d
|
||||
typesense.url: http://ts:8108
|
||||
typesense.apiKey: k
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "S3/object-storage source missing"
|
||||
|
||||
@@ -162,6 +162,13 @@
|
||||
"url": { "type": "string", "pattern": "^(rediss?://.+)?$" }
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"backend": { "type": "string", "enum": ["postgres", "typesense", "disabled"] }
|
||||
}
|
||||
},
|
||||
"typesense": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
# refs everywhere, no chart-side autogeneration, GitOps-safe (ArgoCD/Flux).
|
||||
# HA-ready: replicaCount >= 2 (requires Redis and RWX storage for git).
|
||||
#
|
||||
# QUICKSTART — bundles in-cluster Postgres + Redis + MinIO + Typesense and
|
||||
# auto-generates relay secrets via the `lookup` pattern (NOT GitOps-safe —
|
||||
# see README), single replica, evaluation only. Opt in by enabling each
|
||||
# bundled service: postgresql.enabled, redis.enabled, minio.enabled,
|
||||
# typesense.enabled. See ci/quickstart-values.yaml and the README.
|
||||
# QUICKSTART — bundles in-cluster Postgres + Redis + MinIO and auto-generates
|
||||
# relay secrets via the `lookup` pattern (NOT GitOps-safe — see README),
|
||||
# single replica, evaluation only. Opt in by enabling each bundled service:
|
||||
# postgresql.enabled, redis.enabled, minio.enabled. Typesense is optional only
|
||||
# when search.backend=typesense. See ci/quickstart-values.yaml and the README.
|
||||
#
|
||||
# See examples/argocd-app.yaml and examples/flux-helmrelease.yaml for the
|
||||
# canonical GitOps configurations.
|
||||
@@ -56,8 +56,8 @@ ownerPubkey: ""
|
||||
# BUZZ_GIT_HOOK_HMAC_SECRET — 32+ chars; required when replicaCount > 1
|
||||
# DATABASE_URL — full Postgres URL (preferred over externalPostgresql.url)
|
||||
# REDIS_URL — full Redis URL with auth
|
||||
# TYPESENSE_URL — Typesense base URL
|
||||
# TYPESENSE_API_KEY — Typesense API key
|
||||
# TYPESENSE_URL — Typesense base URL (only when search.backend=typesense)
|
||||
# TYPESENSE_API_KEY — Typesense API key (only when search.backend=typesense)
|
||||
# BUZZ_S3_ACCESS_KEY — S3 access key
|
||||
# BUZZ_S3_SECRET_KEY — S3 secret key
|
||||
secrets:
|
||||
@@ -211,6 +211,13 @@ redis:
|
||||
externalRedis:
|
||||
url: "" # redis://:pass@host:6379
|
||||
|
||||
# ── Search ───────────────────────────────────────────────────────────────────
|
||||
# Postgres FTS is the default. Set backend=typesense only while using the
|
||||
# fallback Typesense index; set backend=disabled to fail NIP-50 search closed
|
||||
# (queries return no hits, without weakening auth/channel filtering).
|
||||
search:
|
||||
backend: postgres # postgres | typesense | disabled
|
||||
|
||||
# ── Typesense ────────────────────────────────────────────────────────────────
|
||||
# Production: point url/apiKey at an external Typesense service (or supply
|
||||
# TYPESENSE_URL/TYPESENSE_API_KEY via secrets.existingSecret).
|
||||
|
||||
Reference in New Issue
Block a user