Storage key format
All backends use the same logical key:recordings/<user_id>/<recording_id>/<session_uid>.<ext>
Example:
recordings/36/42/abc123.wav
Backend options
SetSTORAGE_BACKEND in bot-manager:
local: filesystem directoryminio: S3-compatible object store via MinIO settingss3: cloud object store via AWS/S3 settings
1) Docker Compose (local path)
Use a simple local path in the container:docker-compose.yml mounts a persistent named volume:
- container path:
/data/recordings - volume name:
recordings-data
LOCAL_STORAGE_VOLUME_SOURCE=./data/recordings, files are stored directly under the repo path for easier inspection.
2) Docker Compose (MinIO)
3) Cloud S3
S3_ENDPOINT.
4) Vexa Lite (single container)
Lite supports local backend, but for production you should keep compute stateless and use object storage (s3).
Recommended (stateless, production):
5) Kubernetes
Option A: local filesystem in pod (requires PVC)
Use local backend with a PVC mounted into the bot-manager pod:/data/recordings.
Option B: object storage (recommended)
Useminio (self-hosted) or s3 (managed cloud) and keep bot-manager stateless.
API behavior
- For object storage (
minio/s3):/recordings/{id}/media/{media_id}/downloadreturns a presigned URL./recordings/{id}/media/{media_id}/rawis also available as an authenticated streaming endpoint (useful for browser playback via a same-origin proxy to avoid CORS).
- For local storage (
local):/recordings/{id}/media/{media_id}/downloadreturns an authenticated API path:/recordings/{id}/media/{media_id}/raw
/recordings/{id}/media/{media_id}/rawstreams bytes from the local filesystem.
Browser playback notes
/recordings/{id}/media/{media_id}/raw is designed to support in-browser playback:
Content-Disposition: inline(lets<audio>play it without forcing download)Rangerequests (206 Partial Content) for seeking
Range and returns the upstream response body without JSON parsing.
Operational note (Docker Compose)
Changing.env values (e.g., switching STORAGE_BACKEND) requires recreating containers to apply updated environment variables:
Durability notes
LOCAL_STORAGE_FSYNC=trueforces fsync on writes for local backend.- Local backend durability depends on the underlying disk/volume lifecycle.
- Object storage backends provide independent persistence outside bot process lifecycle.