A video indexing and semantic search application. Point it at folders of video files, and it chunks, embeds, and indexes them for natural-language search.
Install dependencies:
bun installCopy environment files:
cp apps/server/.env.example apps/server/.env
cp apps/web/.env.example apps/web/.envEdit apps/server/.env and set BETTER_AUTH_SECRET to a random 32+ character string.
Generate and apply database migrations:
bun run db:generate
bun run db:migrateStart the dev server:
bun run dev- Web: http://localhost:3001
- API: http://localhost:3000
bun run dev- Start all apps in development modebun run build- Build all appsbun run dev:web- Start only the web appbun run dev:server- Start only the serverbun run check- Run Biome formatting and lintingbun run check-types- Check TypeScript typesbun run db:generate- Generate database migrationsbun run db:migrate- Run database migrationsbun run db:studio- Open Drizzle Studio
indecks uses an external, OpenAI-compatible embedding API to index video content. Each library can have one or more indexers, each pointing at a different provider or model.
An indexer requires:
| Setting | Description |
|---|---|
baseUrl |
API endpoint (e.g., http://localhost:8000/v1) |
apiKey |
Bearer token for authentication |
model |
Model identifier (e.g., Qwen/Qwen3-VL-Embedding-2B) |
dimensions |
Expected embedding vector size (e.g., 2048) |
Any provider that serves an OpenAI-compatible embeddings endpoint works. Tested with Qwen3-VL-Embedding-2B models served via vLLM.
docker pull ghcr.io/chehanr/indecks:latest
docker run -p 3000:3000 -v indecks-data:/data ghcr.io/chehanr/indecks:latestAll data is stored under /data in the container. Mount a volume to persist it across restarts.
Override defaults with environment variables:
docker run -p 3000:3000 \
-v indecks-data:/data \
-e BETTER_AUTH_SECRET=your-secret-here \
-e BETTER_AUTH_URL=http://localhost:3000 \
-e CORS_ORIGIN=http://localhost:3000 \
ghcr.io/chehanr/indecks:latest/livez— Liveness probe (process alive)/readyz— Readiness probe (DB connection OK)
All runtime data lives under a data/ directory (gitignored):
data/
config/ # SQLite database
vector/ # Vector DB files (sqlite-vec)
thumbnails/ # Thumbnail cache
Paths are configurable via environment variables:
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
file:./data/config/local.db |
SQLite database URL |
VECTOR_DIR |
./data/vector |
Vector database directory |
THUMBNAILS_DIR |
./data/thumbnails |
Thumbnail cache directory |
Inspired by SentrySearch — wanted something similar but accessible via a web UI. Built over a weekend.
