Documentation Index Fetch the complete documentation index at: https://mintlify.com/chroma-core/chroma/llms.txt
Use this file to discover all available pages before exploring further.
Chroma provides official Docker images for easy deployment. This guide covers single-instance Docker deployments using the official images.
Quick Start
The fastest way to get Chroma running with Docker:
docker run -p 8000:8000 ghcr.io/chroma-core/chroma:latest
This starts Chroma in ephemeral mode. Data will be lost when the container stops.
Docker Compose (Recommended)
Basic Setup with Persistence
Create a docker-compose.yml file:
version : '3.9'
networks :
net :
driver : bridge
services :
server :
image : ghcr.io/chroma-core/chroma:latest
environment :
- IS_PERSISTENT=TRUE
volumes :
# Default configuration for persist_directory
- chroma-data:/chroma/chroma/
ports :
- 8000:8000
networks :
- net
volumes :
chroma-data :
driver : local
Start the server:
Production Configuration
For production deployments, use the configuration from the Chroma repository:
version : '3.9'
networks :
net :
driver : bridge
services :
server :
image : server
build :
context : .
dockerfile : rust/Dockerfile
target : cli
volumes :
# The default config specifies a persist_directory of /data
- chroma-data:/data
environment :
- CHROMA_OPEN_TELEMETRY__ENDPOINT=${CHROMA_OPEN_TELEMETRY__ENDPOINT}
- CHROMA_OPEN_TELEMETRY__SERVICE_NAME=${CHROMA_OPEN_TELEMETRY__SERVICE_NAME}
- OTEL_EXPORTER_OTLP_HEADERS=${OTEL_EXPORTER_OTLP_HEADERS}
restart : unless-stopped
ports :
- "8000:8000"
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost:8000/api/v2/heartbeat" ]
interval : 30s
timeout : 10s
retries : 3
networks :
- net
volumes :
chroma-data :
driver : local
Environment File
Create a .env file in the same directory:
# Observability (optional)
CHROMA_OPEN_TELEMETRY__ENDPOINT =
CHROMA_OPEN_TELEMETRY__SERVICE_NAME = chromadb
OTEL_EXPORTER_OTLP_HEADERS = {}
Building from Source
Chroma’s official Dockerfile uses a multi-stage build process:
Dockerfile Overview
The Dockerfile (Dockerfile in the repository root) creates a production-ready image:
FROM python:3.11-slim-bookworm AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential gcc g++ cmake autoconf \
python3-dev unzip curl make
# Install Rust toolchain
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
# Install protobuf compiler
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v31.1/protoc-31.1-linux-x86_64.zip && \
unzip -o protoc-*.zip -d /usr/local
# Build Chroma
COPY . /chroma
WORKDIR /chroma
RUN make -C idl proto_python
RUN python3 -m maturin build
RUN pip install --prefix= "/install" --find-links target/wheels/ chromadb
# Final stage
FROM python:3.11-slim-bookworm AS final
COPY --from=builder /install /usr/local
COPY --from=builder /chroma /chroma
ENV CHROMA_HOST_ADDR= "0.0.0.0"
ENV CHROMA_HOST_PORT=8000
ENV CHROMA_WORKERS=1
ENV CHROMA_LOG_CONFIG= "chromadb/log_config.yml"
ENV CHROMA_TIMEOUT_KEEP_ALIVE=30
EXPOSE 8000
ENTRYPOINT [ "/docker_entrypoint.sh" ]
CMD [ "--workers ${CHROMA_WORKERS} --host ${CHROMA_HOST_ADDR} --port ${CHROMA_HOST_PORT} --proxy-headers --reload --log-config ${CHROMA_LOG_CONFIG} --timeout-keep-alive ${CHROMA_TIMEOUT_KEEP_ALIVE}" ]
Build Custom Image
# Build the image
docker build -t my-chroma:latest .
# Run the custom image
docker run -p 8000:8000 -v chroma-data:/chroma/chroma my-chroma:latest
Build Arguments
# Rebuild hnswlib from source (useful for specific CPU architectures)
docker build --build-arg REBUILD_HNSWLIB= true -t my-chroma:latest .
# Specify protobuf version
docker build --build-arg PROTOC_VERSION= 31.1 -t my-chroma:latest .
Environment Variables
Server Configuration
Variable Default Description CHROMA_HOST_ADDR0.0.0.0Host address to bind to CHROMA_HOST_PORT8000Port to listen on CHROMA_WORKERS1Number of worker processes CHROMA_LOG_CONFIGchromadb/log_config.ymlPath to logging configuration CHROMA_TIMEOUT_KEEP_ALIVE30Keep-alive timeout in seconds CHROMA_SERVER_NOFILE65536Maximum number of open files
Persistence
Variable Default Description IS_PERSISTENTFALSEEnable persistent storage PERSIST_DIRECTORY./chromaDirectory for persistent data
Authentication
services :
server :
image : ghcr.io/chroma-core/chroma:latest
environment :
- IS_PERSISTENT=TRUE
- CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.basic_authn.BasicAuthenticationServerProvider
- CHROMA_SERVER_AUTHN_CREDENTIALS_FILE=/chroma/auth/credentials.htpasswd
volumes :
- ./credentials.htpasswd:/chroma/auth/credentials.htpasswd
- chroma-data:/chroma/chroma/
See the Authentication guide for more details.
Observability
services :
server :
image : ghcr.io/chroma-core/chroma:latest
environment :
- IS_PERSISTENT=TRUE
- CHROMA_OTEL_COLLECTION_ENDPOINT=http://jaeger:4317
- CHROMA_OTEL_SERVICE_NAME=chromadb
- OTEL_EXPORTER_OTLP_HEADERS={"x-api-key":"your-key"}
Volume Mounts and Persistence
Data Directory
The default persist directory depends on the configuration:
Python-based image (ghcr.io/chroma-core/chroma):
volumes :
- chroma-data:/chroma/chroma/
Rust-based image (built from source):
volumes :
- chroma-data:/data
Custom Persist Directory
services :
server :
image : ghcr.io/chroma-core/chroma:latest
environment :
- IS_PERSISTENT=TRUE
- PERSIST_DIRECTORY=/custom/path
volumes :
- chroma-data:/custom/path
Backup Data
# Create a backup
docker run --rm -v chroma-data:/data -v $( pwd ) :/backup \
ubuntu tar czf /backup/chroma-backup.tar.gz -C /data .
# Restore from backup
docker run --rm -v chroma-data:/data -v $( pwd ) :/backup \
ubuntu tar xzf /backup/chroma-backup.tar.gz -C /data
Docker Commands
Basic Operations
# Start Chroma
docker-compose up -d
# View logs
docker-compose logs -f
# Stop Chroma
docker-compose down
# Stop and remove volumes
docker-compose down -v
Maintenance
# Check health
curl http://localhost:8000/api/v2/heartbeat
# View running containers
docker-compose ps
# Restart the service
docker-compose restart server
# Update to latest image
docker-compose pull
docker-compose up -d
Healthcheck
The official configuration includes a healthcheck:
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost:8000/api/v2/heartbeat" ]
interval : 30s
timeout : 10s
retries : 3
Check health status:
docker inspect --format= '{{.State.Health.Status}}' < container-i d >
Restart Policies
Configured restart behavior:
restart : unless-stopped # Options: "no", "always", "on-failure", "unless-stopped"
Networking
Custom Network
networks :
chroma-network :
driver : bridge
ipam :
config :
- subnet : 172.28.0.0/16
services :
server :
networks :
chroma-network :
ipv4_address : 172.28.0.2
Expose to External Network
services :
server :
ports :
- "0.0.0.0:8000:8000" # Expose on all interfaces
# or
- "127.0.0.1:8000:8000" # Localhost only
Entrypoint Script
The Docker entrypoint (/docker_entrypoint.sh) handles service startup:
#!/bin/bash
set -e
export IS_PERSISTENT = 1
export CHROMA_SERVER_NOFILE = ${ CHROMA_SERVER_NOFILE :- 65536 }
args = " $@ "
if [[ $args =~ ^uvicorn. * ]]; then
exec $( eval echo " $args " )
else
exec uvicorn chromadb.app:app $( eval echo " $args " )
fi
Troubleshooting
Container Fails to Start
# Check logs
docker-compose logs server
# Check if port is already in use
lsof -i :8000
# Verify volume permissions
docker-compose exec server ls -la /chroma/chroma
Data Not Persisting
Verify IS_PERSISTENT=TRUE is set and volume is mounted:
docker-compose exec server env | grep PERSISTENT
docker volume inspect < volume-nam e >
Increase worker count for better concurrency:
environment :
- CHROMA_WORKERS=4
Next Steps
Configuration Learn about advanced configuration options
Authentication Set up authentication and authorization
Kubernetes Scale to Kubernetes for production
Observability Monitor your Chroma deployment