Skip to content

⚙️ Configuration

Curiositi is configured through environment variables. A single .env.example file at the repository root contains all available configuration options shared across apps.

Copy the example environment file from the repository root:

Terminal window
cp .env.example .env

This single .env file at the root is used by all apps via Turborepo.

The following environment variables are used by Curiositi. All variables listed below are defined in the root .env.example file.

These variables are required by both the platform and worker apps:

Note: POSTGRES_URL is directly used by the @curiositi/db package. The platform accesses the database through this shared package, so the variable is not explicitly validated in the platform’s env.ts.

VariableRequiredDescription
POSTGRES_URLYesPostgreSQL connection string
S3_ENDPOINTYesS3-compatible storage endpoint URL
S3_BUCKETYesS3 bucket name
S3_ACCESS_KEY_IDYesS3 access key
S3_SECRET_ACCESS_KEYYesS3 secret key

Connection string format:

postgresql://[user[:password]@][host][:port][/dbname][?param1=value1&...]
VariableRequiredDescription
PLATFORM_URLYesPublic URL of the platform app (default: http://localhost:3030)
WORKER_URLYesURL of the worker service (default: http://localhost:3040)
BETTER_AUTH_SECRETYesSecret key for Better Auth session signing
BETTER_AUTH_GOOGLE_CLIENT_IDYesGoogle OAuth client ID
BETTER_AUTH_GOOGLE_CLIENT_SECRETYesGoogle OAuth client secret
QUEUE_PROVIDERNoQueue provider: "qstash" (default, cloud) or "local" (self-hosted bunqueue)
QSTASH_TOKENConditionalUpstash QStash token (required if QUEUE_PROVIDER=qstash)
QSTASH_URLNoCustom QStash URL (uses default Upstash endpoint if not set)
BUNQUEUE_HOSTConditionalbunqueue server host (required if QUEUE_PROVIDER=local, default: localhost)
BUNQUEUE_PORTConditionalbunqueue server port (required if QUEUE_PROVIDER=local, default: 6789)
VariableRequiredDescription
VITE_APP_TITLENoApplication title displayed in the browser
VITE_SENTRY_DSNNoSentry DSN for error tracking
VITE_SENTRY_ORGNoSentry organization slug
VITE_SENTRY_PROJECTNoSentry project slug
VariableRequiredDescription
SENTRY_AUTH_TOKENNoSentry auth token for source map uploads
Terminal window
# === SHARED (Platform & Worker) ===
# Database - Connection string for the PostgreSQL database
POSTGRES_URL=""
# File Storage - S3 compatible storage settings for AWS, GCP, or Cloudflare R2
S3_ENDPOINT=""
S3_BUCKET=""
S3_ACCESS_KEY_ID=""
S3_SECRET_ACCESS_KEY=""
# === PLATFORM ONLY ===
# Server Configuration
PLATFORM_URL="http://localhost:3030"
WORKER_URL="http://localhost:3040"
# Authentication - Better Auth configuration and Google OAuth credentials
BETTER_AUTH_SECRET=""
BETTER_AUTH_GOOGLE_CLIENT_ID=""
BETTER_AUTH_GOOGLE_CLIENT_SECRET=""
# Queue Configuration
# QUEUE_PROVIDER: "qstash" (default, cloud) or "local" (self-hosted bunqueue)
QUEUE_PROVIDER="qstash"
# QStash (required if QUEUE_PROVIDER=qstash)
QSTASH_TOKEN=""
QSTASH_URL=""
# bunqueue (required if QUEUE_PROVIDER=local)
BUNQUEUE_HOST="localhost"
BUNQUEUE_PORT="6789"
# Monitoring & Error Tracking - Sentry (optional)
VITE_SENTRY_DSN=""
VITE_SENTRY_ORG=""
VITE_SENTRY_PROJECT=""
SENTRY_AUTH_TOKEN=""

Both the platform and worker validate environment variables at startup using @t3-oss/env-core with Zod schemas. Missing required variables will cause the application to fail fast with a clear error message.

Platform validation (apps/platform/src/env.ts):

import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";
export const env = createEnv({
server: {
PLATFORM_URL: z.url(),
QUEUE_PROVIDER: z.enum(["qstash", "local"]).default("qstash"),
QSTASH_TOKEN: z.string().optional(),
WORKER_URL: z.string(),
BUNQUEUE_HOST: z.string().default("localhost"),
BUNQUEUE_PORT: z.coerce.number().default(6789),
BETTER_AUTH_GOOGLE_CLIENT_ID: z.string(),
BETTER_AUTH_GOOGLE_CLIENT_SECRET: z.string(),
BETTER_AUTH_SECRET: z.string(),
S3_ACCESS_KEY_ID: z.string(),
S3_SECRET_ACCESS_KEY: z.string(),
S3_BUCKET: z.string(),
S3_ENDPOINT: z.string(),
},
client: {
VITE_APP_TITLE: z.string().min(1).optional(),
VITE_SENTRY_DSN: z.string().optional(),
VITE_SENTRY_ORG: z.string().optional(),
VITE_SENTRY_PROJECT: z.string().optional(),
},
// Conditional validation happens at runtime after env is loaded
});

The platform performs conditional validation based on QUEUE_PROVIDER:

  • If qstash: requires QSTASH_TOKEN
  • If local: requires BUNQUEUE_HOST and BUNQUEUE_PORT (defaults available)

WORKER_URL is always required.

Worker validation (apps/worker/src/env.ts):

import { createEnv } from "@t3-oss/env-core";
import { z } from "zod";
export const env = createEnv({
server: {
S3_ACCESS_KEY_ID: z.string(),
S3_SECRET_ACCESS_KEY: z.string(),
S3_BUCKET: z.string(),
S3_ENDPOINT: z.string(),
POSTGRES_URL: z.url(),
QUEUE_PROVIDER: z.enum(["qstash", "local"]).default("qstash"),
BUNQUEUE_HOST: z.string().default("localhost"),
BUNQUEUE_PORT: z.coerce.number().default(6789),
},
// ...
});

Some configuration values are set directly in code rather than through environment variables:

SettingValueLocation
Max file size50MBpackages/share/src/constants/index.ts
Large image threshold5MBpackages/share/src/constants/index.ts
Chunk size800 tokensapps/worker/src/lib/chunk.ts
Chunk overlap100 tokensapps/worker/src/lib/chunk.ts
Embedding dimensions1536packages/db/src/schema.ts

AI model names are hardcoded in packages/share/src/ai/index.ts:

ProviderEmbedding ModelText Model
OpenAItext-embedding-3-smallgpt-5-mini-2025-08-07
Googlegemini-embedding-001gemini-3-flash-preview
AppPortConfiguration
Platform3030apps/platform/package.json dev script
Worker3040apps/worker/src/index.ts

Docker:

Terminal window
docker run -d \
--name curiositi-db \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=curiositi \
-p 5432:5432 \
pgvector/pgvector:pg16

Verify pgvector:

Terminal window
psql -h localhost -U postgres -d curiositi -c "CREATE EXTENSION IF NOT EXISTS vector;"

Docker:

Terminal window
docker run -d \
--name curiositi-minio \
-p 9000:9000 \
-p 9001:9001 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
minio/minio server /data --console-address ":9001"

Create bucket:

Terminal window
mc alias set local http://localhost:9000 minioadmin minioadmin
mc mb local/curiositi-dev

For local development without Upstash QStash, you can use bunqueue - a lightweight queue built on Bun.

Start the bunqueue server:

Terminal window
# Using the queue package dev script
cd packages/queue && bun run dev
# Or run directly
bunx bunqueue start --port 6789 --data-path ./queue.db

Configure environment:

Terminal window
QUEUE_PROVIDER=local
BUNQUEUE_HOST=localhost
BUNQUEUE_PORT=6789

The bunqueue server stores jobs in a local SQLite database (queue.db). Add the following to .gitignore:

queue.db
queue.db-shm
queue.db-wal
Terminal window
# Test connection
psql $POSTGRES_URL -c "SELECT 1"
# Check pgvector
psql $POSTGRES_URL -c "SELECT * FROM pg_extension WHERE extname = 'vector'"
Terminal window
# Test S3 access
aws s3 ls s3://$S3_BUCKET --endpoint-url=$S3_ENDPOINT