551 lines
13 KiB
Plaintext
551 lines
13 KiB
Plaintext
---
|
|
title: "Storage"
|
|
description: "Configure Bifrost storage backends in Helm — SQLite, PostgreSQL (embedded and external), per-store overrides, and S3/GCS object storage for logs"
|
|
icon: "database"
|
|
---
|
|
|
|
Bifrost persists two types of data — **config** (providers, virtual keys, governance rules) and **logs** (request/response records). Each has its own store, both defaulting to the top-level `storage.mode`.
|
|
|
|
| Parameter | Description | Default |
|
|
|-----------|-------------|---------|
|
|
| `storage.mode` | Default backend for both stores (`sqlite` or `postgres`) | `sqlite` |
|
|
| `storage.configStore.type` | Override backend for the config store | `""` (inherits `storage.mode`) |
|
|
| `storage.logsStore.type` | Override backend for the logs store | `""` (inherits `storage.mode`) |
|
|
|
|
<Note>
|
|
When any store uses SQLite the chart deploys a **StatefulSet** with a PVC. With PostgreSQL only (no SQLite) it deploys a **Deployment**. Mixing backends (e.g. config=postgres, logs=sqlite) still requires a StatefulSet.
|
|
</Note>
|
|
|
|
---
|
|
|
|
<Tabs>
|
|
|
|
<Tab title="SQLite">
|
|
|
|
### SQLite (Default)
|
|
|
|
Simplest setup — no external database required. Bifrost runs as a StatefulSet with a persistent volume for the SQLite files.
|
|
|
|
| Parameter | Description | Default |
|
|
|-----------|-------------|---------|
|
|
| `storage.persistence.enabled` | Create a PVC for SQLite data | `true` |
|
|
| `storage.persistence.size` | PVC size | `10Gi` |
|
|
| `storage.persistence.accessMode` | PVC access mode | `ReadWriteOnce` |
|
|
| `storage.persistence.storageClass` | Storage class (leave empty for cluster default) | `""` |
|
|
| `storage.persistence.existingClaim` | Reuse an existing PVC | `""` |
|
|
|
|
```yaml
|
|
# sqlite-values.yaml
|
|
image:
|
|
tag: "v1.4.11"
|
|
|
|
storage:
|
|
mode: sqlite
|
|
persistence:
|
|
enabled: true
|
|
size: 20Gi
|
|
# storageClass: "gp3" # uncomment to pin storage class
|
|
|
|
bifrost:
|
|
encryptionKey: "your-32-byte-encryption-key-here"
|
|
```
|
|
|
|
```bash
|
|
helm install bifrost bifrost/bifrost -f sqlite-values.yaml
|
|
```
|
|
|
|
**Reuse an existing PVC** (e.g. after a StatefulSet migration):
|
|
|
|
```yaml
|
|
storage:
|
|
persistence:
|
|
existingClaim: "bifrost-data"
|
|
```
|
|
|
|
<Warning>
|
|
Upgrading from SQLite to PostgreSQL requires a data migration — the two stores are not compatible. Plan accordingly before switching `storage.mode` on a running deployment.
|
|
</Warning>
|
|
|
|
#### StatefulSet Migration (chart v2.0.0+)
|
|
|
|
Prior to v2.0.0, SQLite used a Deployment + manual PVC. v2.0.0 moved SQLite to a StatefulSet. If upgrading from an older chart:
|
|
|
|
```bash
|
|
# 1. Scale down the old deployment
|
|
kubectl scale deployment bifrost --replicas=0
|
|
|
|
# 2. Note the existing PVC name
|
|
kubectl get pvc
|
|
|
|
# 3. Upgrade the chart, pointing at the existing claim
|
|
helm upgrade bifrost bifrost/bifrost \
|
|
--reuse-values \
|
|
--set storage.persistence.existingClaim=<your-old-pvc-name> \
|
|
--set image.tag=v1.4.11
|
|
```
|
|
|
|
</Tab>
|
|
|
|
<Tab title="Embedded PostgreSQL">
|
|
|
|
### Embedded PostgreSQL
|
|
|
|
The chart can deploy a PostgreSQL instance alongside Bifrost. Good for simple production setups where you don't have an existing database.
|
|
|
|
| Parameter | Description | Default |
|
|
|-----------|-------------|---------|
|
|
| `storage.mode` | Set to `postgres` | `sqlite` |
|
|
| `postgresql.enabled` | Deploy PostgreSQL as a sub-deployment | `false` |
|
|
| `postgresql.auth.username` | Database user | `bifrost` |
|
|
| `postgresql.auth.password` | Database password | `bifrost_password` |
|
|
| `postgresql.auth.database` | Database name | `bifrost` |
|
|
| `postgresql.primary.persistence.size` | PVC size for PostgreSQL data | `8Gi` |
|
|
|
|
<Note>
|
|
Ensure the database is created with **UTF8 encoding**. The embedded PostgreSQL deployment handles this automatically. See [PostgreSQL UTF8 Requirement](/quickstart/gateway/setting-up#postgresql-utf8-requirement) for manual setups.
|
|
</Note>
|
|
|
|
```bash
|
|
kubectl create secret generic postgres-credentials \
|
|
--from-literal=password='your-secure-postgres-password'
|
|
```
|
|
|
|
```yaml
|
|
# embedded-postgres-values.yaml
|
|
image:
|
|
tag: "v1.4.11"
|
|
|
|
storage:
|
|
mode: postgres
|
|
|
|
postgresql:
|
|
enabled: true
|
|
auth:
|
|
username: bifrost
|
|
password: "your-secure-postgres-password" # use existingSecret in production
|
|
database: bifrost
|
|
primary:
|
|
persistence:
|
|
enabled: true
|
|
size: 50Gi
|
|
resources:
|
|
requests:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
limits:
|
|
cpu: 2000m
|
|
memory: 4Gi
|
|
|
|
bifrost:
|
|
encryptionKey: "your-32-byte-encryption-key-here"
|
|
```
|
|
|
|
```bash
|
|
helm install bifrost bifrost/bifrost -f embedded-postgres-values.yaml
|
|
```
|
|
|
|
**Verify the connection from Bifrost:**
|
|
|
|
```bash
|
|
kubectl exec -it deployment/bifrost -- nc -zv bifrost-postgresql 5432
|
|
```
|
|
|
|
</Tab>
|
|
|
|
<Tab title="External PostgreSQL">
|
|
|
|
### External PostgreSQL
|
|
|
|
Point Bifrost at an existing PostgreSQL instance — RDS, Cloud SQL, Azure Database, or self-managed.
|
|
|
|
| Parameter | Description | Default |
|
|
|-----------|-------------|---------|
|
|
| `postgresql.enabled` | Must be `false` | `false` |
|
|
| `postgresql.external.enabled` | Enable external connection | `false` |
|
|
| `postgresql.external.host` | Hostname or IP | `""` |
|
|
| `postgresql.external.port` | Port | `5432` |
|
|
| `postgresql.external.user` | Username | `bifrost` |
|
|
| `postgresql.external.database` | Database name | `bifrost` |
|
|
| `postgresql.external.sslMode` | SSL mode (`disable`, `require`, `verify-ca`, `verify-full`) | `disable` |
|
|
| `postgresql.external.existingSecret` | Secret name for the password | `""` |
|
|
| `postgresql.external.passwordKey` | Key within the secret | `"password"` |
|
|
|
|
```bash
|
|
kubectl create secret generic external-postgres-credentials \
|
|
--from-literal=password='your-external-postgres-password'
|
|
```
|
|
|
|
```yaml
|
|
# external-postgres-values.yaml
|
|
image:
|
|
tag: "v1.4.11"
|
|
|
|
storage:
|
|
mode: postgres
|
|
|
|
postgresql:
|
|
enabled: false
|
|
external:
|
|
enabled: true
|
|
host: "your-rds-endpoint.us-east-1.rds.amazonaws.com"
|
|
port: 5432
|
|
user: bifrost
|
|
database: bifrost
|
|
sslMode: require
|
|
existingSecret: "external-postgres-credentials"
|
|
passwordKey: "password"
|
|
|
|
bifrost:
|
|
encryptionKey: "your-32-byte-encryption-key-here"
|
|
```
|
|
|
|
```bash
|
|
helm install bifrost bifrost/bifrost -f external-postgres-values.yaml
|
|
```
|
|
|
|
**Test connectivity before installing:**
|
|
|
|
```bash
|
|
kubectl run pg-test --image=postgres:16-alpine --rm -it --restart=Never -- \
|
|
psql "host=your-rds-endpoint.us-east-1.rds.amazonaws.com dbname=bifrost user=bifrost sslmode=require" \
|
|
-c "SELECT version();"
|
|
```
|
|
|
|
</Tab>
|
|
|
|
<Tab title="Mixed (Config=Postgres, Logs=SQLite)">
|
|
|
|
### Mixed Backend
|
|
|
|
Run the config store on PostgreSQL (fast lookups, shared across replicas) while keeping logs on SQLite (simpler, cheaper for append-heavy workloads).
|
|
|
|
```yaml
|
|
# mixed-values.yaml
|
|
image:
|
|
tag: "v1.4.11"
|
|
|
|
storage:
|
|
mode: sqlite # default fallback
|
|
configStore:
|
|
type: postgres # override: config uses postgres
|
|
logsStore:
|
|
type: sqlite # explicit: logs use sqlite
|
|
persistence:
|
|
enabled: true
|
|
size: 20Gi # for the SQLite logs store
|
|
|
|
postgresql:
|
|
external:
|
|
enabled: true
|
|
host: "your-postgres-host.example.com"
|
|
port: 5432
|
|
user: bifrost
|
|
database: bifrost
|
|
sslMode: require
|
|
existingSecret: "postgres-credentials"
|
|
passwordKey: "password"
|
|
|
|
bifrost:
|
|
encryptionKey: "your-32-byte-encryption-key-here"
|
|
```
|
|
|
|
```bash
|
|
kubectl create secret generic postgres-credentials \
|
|
--from-literal=password='your-postgres-password'
|
|
|
|
helm install bifrost bifrost/bifrost -f mixed-values.yaml
|
|
```
|
|
|
|
<Note>
|
|
In mixed mode, Bifrost deploys a StatefulSet (because SQLite is in use) with both a PostgreSQL connection and a local PVC for the SQLite log store.
|
|
</Note>
|
|
|
|
**PostgreSQL connection pool tuning** (high log volume):
|
|
|
|
```yaml
|
|
storage:
|
|
configStore:
|
|
type: postgres
|
|
maxIdleConns: 5
|
|
maxOpenConns: 50
|
|
logsStore:
|
|
type: postgres
|
|
maxIdleConns: 10
|
|
maxOpenConns: 100
|
|
```
|
|
|
|
</Tab>
|
|
|
|
</Tabs>
|
|
|
|
---
|
|
|
|
## Object Storage for Logs
|
|
|
|
Offload large request/response payloads from the database to S3 or GCS. The DB retains only lightweight index records; payloads are fetched on demand.
|
|
|
|
<Tabs>
|
|
<Tab title="AWS S3">
|
|
|
|
```bash
|
|
kubectl create secret generic s3-credentials \
|
|
--from-literal=access-key-id='AKIAIOSFODNN7EXAMPLE' \
|
|
--from-literal=secret-access-key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
|
|
```
|
|
|
|
```yaml
|
|
storage:
|
|
logsStore:
|
|
objectStorage:
|
|
enabled: true
|
|
type: s3
|
|
bucket: "bifrost-logs"
|
|
prefix: "bifrost"
|
|
compress: true # gzip compression
|
|
|
|
# S3 configuration
|
|
region: us-east-1
|
|
accessKeyId: "env.S3_ACCESS_KEY_ID"
|
|
secretAccessKey: "env.S3_SECRET_ACCESS_KEY"
|
|
# endpoint: "" # Custom endpoint for MinIO / Cloudflare R2
|
|
# forcePathStyle: false # Set true for MinIO
|
|
|
|
bifrost:
|
|
# inject S3 credentials as env vars
|
|
providerSecrets:
|
|
s3-access-key:
|
|
existingSecret: "s3-credentials"
|
|
key: "access-key-id"
|
|
envVar: "S3_ACCESS_KEY_ID"
|
|
s3-secret-key:
|
|
existingSecret: "s3-credentials"
|
|
key: "secret-access-key"
|
|
envVar: "S3_SECRET_ACCESS_KEY"
|
|
```
|
|
|
|
**Using IAM role (IRSA / instance profile) instead of static keys:**
|
|
|
|
```yaml
|
|
storage:
|
|
logsStore:
|
|
objectStorage:
|
|
enabled: true
|
|
type: s3
|
|
bucket: "bifrost-logs"
|
|
region: us-east-1
|
|
# No accessKeyId / secretAccessKey — uses SDK default chain
|
|
roleArn: "arn:aws:iam::123456789012:role/BifrostS3Role"
|
|
```
|
|
|
|
</Tab>
|
|
<Tab title="Google Cloud Storage">
|
|
|
|
```bash
|
|
kubectl create secret generic gcs-credentials \
|
|
--from-literal=service-account-json="$(cat service-account-key.json)"
|
|
```
|
|
|
|
```yaml
|
|
storage:
|
|
logsStore:
|
|
objectStorage:
|
|
enabled: true
|
|
type: gcs
|
|
bucket: "bifrost-logs"
|
|
prefix: "bifrost"
|
|
compress: true
|
|
|
|
# GCS configuration
|
|
projectId: "my-gcp-project"
|
|
credentialsJson: "env.GCS_CREDENTIALS_JSON" # omit for Workload Identity
|
|
|
|
bifrost:
|
|
providerSecrets:
|
|
gcs-creds:
|
|
existingSecret: "gcs-credentials"
|
|
key: "service-account-json"
|
|
envVar: "GCS_CREDENTIALS_JSON"
|
|
```
|
|
|
|
</Tab>
|
|
<Tab title="MinIO (Self-Hosted)">
|
|
|
|
```yaml
|
|
storage:
|
|
logsStore:
|
|
objectStorage:
|
|
enabled: true
|
|
type: s3
|
|
bucket: "bifrost-logs"
|
|
prefix: "bifrost"
|
|
compress: false
|
|
|
|
region: us-east-1 # can be any value for MinIO
|
|
endpoint: "http://minio.minio-ns.svc.cluster.local:9000"
|
|
accessKeyId: "env.MINIO_ACCESS_KEY"
|
|
secretAccessKey: "env.MINIO_SECRET_KEY"
|
|
forcePathStyle: true # required for MinIO
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
```bash
|
|
helm upgrade bifrost bifrost/bifrost \
|
|
--reuse-values \
|
|
-f object-storage-values.yaml
|
|
```
|
|
|
|
---
|
|
|
|
## Vector Store
|
|
|
|
A vector store is required for [semantic caching](/deployment-guides/helm/plugins). Choose from Weaviate, Redis, or Qdrant (embedded or external), or Pinecone (external only).
|
|
|
|
<Tabs>
|
|
<Tab title="Weaviate">
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: weaviate
|
|
weaviate:
|
|
enabled: true # deploy embedded Weaviate
|
|
replicas: 1
|
|
persistence:
|
|
enabled: true
|
|
size: 20Gi
|
|
resources:
|
|
requests:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
limits:
|
|
cpu: 2000m
|
|
memory: 4Gi
|
|
```
|
|
|
|
**External Weaviate:**
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: weaviate
|
|
weaviate:
|
|
enabled: false
|
|
external:
|
|
enabled: true
|
|
scheme: https
|
|
host: "weaviate.example.com"
|
|
apiKey: "env.WEAVIATE_API_KEY"
|
|
grpcHost: "weaviate-grpc.example.com"
|
|
grpcSecured: true
|
|
existingSecret: "weaviate-credentials"
|
|
apiKeyKey: "api-key"
|
|
```
|
|
|
|
</Tab>
|
|
<Tab title="Redis / Valkey">
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: redis
|
|
redis:
|
|
enabled: true # deploy embedded Redis
|
|
auth:
|
|
enabled: true
|
|
password: "redis_password"
|
|
master:
|
|
persistence:
|
|
size: 8Gi
|
|
```
|
|
|
|
**External Redis / AWS MemoryDB:**
|
|
|
|
```bash
|
|
kubectl create secret generic redis-credentials \
|
|
--from-literal=password='your-redis-password'
|
|
```
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: redis
|
|
redis:
|
|
enabled: false
|
|
external:
|
|
enabled: true
|
|
host: "your-redis.cache.amazonaws.com"
|
|
port: 6379
|
|
useTls: true
|
|
clusterMode: true # required for AWS MemoryDB
|
|
existingSecret: "redis-credentials"
|
|
passwordKey: "password"
|
|
```
|
|
|
|
</Tab>
|
|
<Tab title="Qdrant">
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: qdrant
|
|
qdrant:
|
|
enabled: true # deploy embedded Qdrant
|
|
persistence:
|
|
size: 10Gi
|
|
```
|
|
|
|
**External Qdrant:**
|
|
|
|
```bash
|
|
kubectl create secret generic qdrant-credentials \
|
|
--from-literal=api-key='your-qdrant-api-key'
|
|
```
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: qdrant
|
|
qdrant:
|
|
enabled: false
|
|
external:
|
|
enabled: true
|
|
host: "qdrant.example.com"
|
|
port: 6334
|
|
useTls: true
|
|
existingSecret: "qdrant-credentials"
|
|
apiKeyKey: "api-key"
|
|
```
|
|
|
|
</Tab>
|
|
<Tab title="Pinecone">
|
|
|
|
Pinecone is external-only.
|
|
|
|
```bash
|
|
kubectl create secret generic pinecone-credentials \
|
|
--from-literal=api-key='your-pinecone-api-key'
|
|
```
|
|
|
|
```yaml
|
|
vectorStore:
|
|
enabled: true
|
|
type: pinecone
|
|
pinecone:
|
|
external:
|
|
enabled: true
|
|
indexHost: "your-index.svc.us-east1-gcp.pinecone.io"
|
|
existingSecret: "pinecone-credentials"
|
|
apiKeyKey: "api-key"
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
```bash
|
|
helm install bifrost bifrost/bifrost \
|
|
--set image.tag=v1.4.11 \
|
|
-f storage-values.yaml
|
|
```
|