Files
bifrost/docs/deployment-guides/helm/storage.mdx
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

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
```