iris is a Go image search engine with a Google Images-style UI.
- Text-to-Image Search: Find images using natural language queries.
- Reverse Image Search: Find visually similar images via upload or URL.
- Smart Indexing: Crawl remote URLs, domains, sitemaps, or local directories.
- Multi-Encoder Retrieval: Index with multiple vision encoders and select the encoder used at search time.
- High Performance: Powered by Python encoder sidecars and Qdrant vector database.
┌──────────────────────────────────────────────────────────┐
│ Client │
└───────────────┬──────────────────────────────┬───────────┘
│ │
Search traffic Index/admin traffic
│ │
┌───────▼──────────────────────────────▼───────┐
│ Go API Server │
│ cmd/server │
└──────────────┬───────────────────┬───────────┘
│ │
gRPC gRPC
│ │
┌─────────▼───────┐ ┌───────▼─────────┐
│ Python Encoders │ │ Qdrant │
│ CLIP + SigLIP2 │ │ vector DB │
└─────────────────┘ └─────────────────┘
┌──────────────────────────────────────────────┐
│ Shared Ingestion Pipeline │
│ internal/indexing │
└──────────────┬───────────────────────┬───────┘
│ │
cmd/indexer cmd/worker
docker compose -f infra/docker-compose.yml up --buildOr, with just installed:
just devVisit http://localhost:8080 to use the UI.
| Service | Port | Purpose |
|---|---|---|
server |
8080 | Main API and Web UI |
qdrant |
6333 | Vector Database |
clip |
8001 | CLIP Embedding gRPC Service |
siglip2 |
8002 | SigLIP2 Embedding gRPC Service |
postgres |
5432 | Worker Job Store |
grafana |
3000 | Observability Dashboard |
The Go services talk to encoder sidecars over gRPC.
- CLIP address:
CLIP_ADDR(defaultlocalhost:8001) - SigLIP2 address:
SIGLIP2_ADDR(optional, no default) - Default search encoder:
DEFAULT_SEARCH_ENCODER(defaultclip) - Qdrant stores one named vector per encoder for each image record
Current encoder names:
clipsiglip2
The encoder protobuf contract currently lives at proto/clip/v1/clip.proto and is shared by both sidecars.
If you change the protobuf contract, regenerate stubs with:
just protoThis updates:
- Go stubs in
internal/clip/clipv1 - Python stubs in
clip_service/clip/v1
- < 1M images: Single Qdrant node.
- 1M – 50M: Qdrant with on-disk payload + HNSW.
- High ingest volume: Move worker jobs to Postgres and split workloads.
- GPU available: Run CLIP sidecar on CUDA for faster embeddings.
- Multiple encoders: Reindex after enabling a new encoder so all stored records receive every named vector.
cmd/: Entry points for server, indexer, and worker.internal/: Core logic (API, crawl, indexing, search).web/: Frontend templates and assets.proto/: Shared protobuf contracts.clip_service/: Python CLIP gRPC service.infra/: Docker and environment configuration.