This guide explains how to run CodeWeaver using Docker and Docker Compose, providing an easy setup with integrated Qdrant vector database.
- Docker Engine 20.10+
- Docker Compose v2.0+
- At least 4GB RAM available
- Your codebase to index
The fastest way to get started uses the quickstart profile with free, local models:
# 1. Get the configuration files
curl -O https://raw.githubusercontent.com/knitli/codeweaver/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/knitli/codeweaver/main/.env.example
cp .env.example .env
# 2. Start services (uses free local models by default)
docker compose up -d
# 3. Check health
curl http://localhost:9328/health/That's it! CodeWeaver will index the current directory using free, local embedding models.
For better search quality, use the recommended profile with Voyage AI:
# Set your API key and profile
export VOYAGE_API_KEY=your-voyage-api-key
export CODEWEAVER_PROFILE=recommended
docker compose up -dGet a free Voyage API key at voyageai.com.
CodeWeaver uses profiles to simplify configuration. Each profile pre-configures providers and models:
| Profile | Description | API Keys Required | Use Case |
|---|---|---|---|
quickstart |
FastEmbed/Sentence Transformers (free, local) | None | Getting started, offline use |
recommended |
Voyage AI (high-quality cloud models) | VOYAGE_API_KEY |
Production, best quality |
backup |
Lightest local models + in-memory vectors | None | Testing, minimal resources |
# Via environment variable
CODEWEAVER_PROFILE=quickstart docker compose up -d
# Or in .env file
CODEWEAVER_PROFILE=recommended- Embeddings: FastEmbed or Sentence Transformers (local)
- Reranking: FastEmbed or Sentence Transformers (local)
- Vector Store: Qdrant (local container)
- Best for: Getting started quickly, offline development
- Embeddings: Voyage AI
voyage-code-3 - Reranking: Voyage AI
voyage-rerank-2.5 - Vector Store: Qdrant (local container)
- Best for: Production use, highest search quality
- Embeddings: Lightest available local model
- Reranking: Lightest available local model
- Vector Store: In-memory (no Qdrant needed)
- Best for: Testing, CI/CD, minimal resource usage
CodeWeaver uses Docker bind mounts to access your codebase:
- Live sync: Changes you make locally appear instantly in the container
- Read-only: The
:roflag prevents CodeWeaver from modifying your code - Direct access: No copying - CodeWeaver reads your actual files
- File watching: CodeWeaver monitors for changes and re-indexes automatically
Set PROJECT_PATH in your .env file:
# Absolute path (recommended)
PROJECT_PATH=/home/user/projects/my-app
# Relative path (relative to docker-compose.yml)
PROJECT_PATH=../my-app
# Current directory
PROJECT_PATH=.The codebase is mounted at /workspace inside the container.
# .env
PROJECT_PATH=/home/user/projects/my-app# Or via command line
PROJECT_PATH=/home/user/projects/my-app docker compose up -dKeep docker-compose.yml in your project directory:
my-project/
├── docker-compose.yml
├── .env
├── src/
└── ...
# .env
PROJECT_PATH=.This mirrors devcontainer behavior where the compose file lives with your code.
# Index only the backend
PROJECT_PATH=/home/user/monorepo/packages/backendCodeWeaver continuously monitors your codebase while the server is running:
- New files: Automatically indexed
- Modified files: Re-indexed on detection
- Deleted files: Removed from index
This happens automatically - no action required.
Force a full re-index if needed:
# Via CLI
docker compose exec codeweaver codeweaver index --force
# Check indexing status
curl http://localhost:9328/health/ | jq '.indexing'Use forward slashes or escaped backslashes:
# .env (Windows)
PROJECT_PATH=C:/Users/me/projects/my-appWSL2 users: For best performance, keep your code in the Linux filesystem:
PROJECT_PATH=/home/user/projects/my-app # Fast
# Not: PROJECT_PATH=/mnt/c/Users/... # SlowDocker Desktop for Mac uses gRPC-FUSE for mounts. For large codebases:
- Enable VirtioFS in Docker Desktop settings
- Configure exclude patterns (see Performance section)
Native bind mounts - best performance. Ensure the Docker user can read your files:
chmod -R o+r /path/to/your/projectCodeWeaver stores critical data that must persist between container restarts:
- Index checkpoints: Resume indexing after restart (avoid re-indexing from scratch)
- Project state: Track which files have been indexed
- Generated config: Profile-based configuration file
- Secrets: API keys configured via
cw init
The docker-compose.yml configures persistence via XDG_CONFIG_HOME:
environment:
- XDG_CONFIG_HOME=/app/config
volumes:
- codeweaver_config:/app/config # Checkpoints, config, secrets
- codeweaver_data:/app/data # Application dataImportant: Without this persistence, CodeWeaver re-indexes from scratch on every restart. For large codebases, this can take significant time.
# View checkpoint data
docker compose exec codeweaver ls -la /app/config/codeweaver/
# Check index status
curl http://localhost:9328/health/ | jq '.indexing'To force a fresh re-index:
# Remove checkpoint data
docker compose exec codeweaver rm -rf /app/config/codeweaver/checkpoints/
# Restart to re-index
docker compose restart codeweaver| Data Type | Container Path | Mounted Volume |
|---|---|---|
| Config & Checkpoints | /app/config/codeweaver/ |
codeweaver_config |
| Application Data | /app/data/ |
codeweaver_data |
| Vector Database | (Qdrant container) | qdrant_storage |
For full control beyond profiles, create your own codeweaver.toml.
CodeWeaver automatically finds configuration files in these locations (in order of precedence):
In your project (mounted at /workspace):
codeweaver.local.toml/.yaml/.jsoncodeweaver.toml/.yaml/.json.codeweaver.local.toml/.yaml/.json.codeweaver.toml/.yaml/.json.codeweaver/codeweaver.local.toml/.yaml/.json.codeweaver/codeweaver.toml/.yaml/.json
User config directory (/app/config/codeweaver/ in Docker):
codeweaver.toml/.yaml/.json
The entrypoint generates config to the user config dir. You can override by placing a config in your project root.
# Install CodeWeaver locally (or use pipx)
pipx install code-weaver
# Generate a config file
cw init config --profile quickstart --config-path ./codeweaver.toml
# Edit as needed
vim codeweaver.toml
# Mount in docker-compose.yml# Start container (generates config from profile)
docker compose up -d
# Copy config out
docker cp codeweaver-server:/app/config/codeweaver/codeweaver.toml ./codeweaver.toml
# Edit locally
vim codeweaver.tomlOption 1: Place in project root (recommended)
Simply add codeweaver.toml to your project - CodeWeaver auto-discovers it:
my-project/
├── codeweaver.toml # Auto-discovered!
├── src/
└── ...
Option 2: Mount to user config location
For config outside your project, mount explicitly in docker-compose.yml:
volumes:
- ${PROJECT_PATH:-.}:/workspace:ro
- codeweaver_config:/app/config
- ./my-config.toml:/app/config/codeweaver/codeweaver.toml:ro # Add thisproject_name = "my-project"
project_path = "/workspace"
token_limit = 30000
[provider.embedding]
provider = "voyage"
model_settings = { model = "voyage-code-3" }
[provider.vector_store]
provider = "qdrant"
provider_settings = {
url = "http://qdrant:6333", # Docker network hostname
collection_name = "my-collection"
}
[indexer]
exclude_patterns = ["node_modules", ".git", "dist", "__pycache__"]Important: When using the local Qdrant container, use http://qdrant:6333 (Docker network hostname), not localhost.
CodeWeaver uses a daemon architecture with stdio as the default transport:
Standalone/docker-compose mode (HTTP transport):
┌─────────────────────────────────────────────────┐
│ CodeWeaver Container │
│ ├─ MCP Server (port 9328, HTTP) │
│ ├─ Management Server (port 9329) │
│ ├─ Live File Watcher │
│ ├─ Indexing Engine │
│ └─ Search API │
│ Connects to ↓ │
└─────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────┐
│ Qdrant Container │
│ ├─ Vector Database (port 6333) │
│ ├─ gRPC API (port 6334) │
│ └─ Persistent Storage │
└─────────────────────────────────────────────────┘
MCP client spawned mode (STDIO transport - default):
┌──────────────────┐ ┌──────────────────────────┐
│ MCP Client │────▶│ Docker Container │
│ (Claude, etc.) │stdio│ └─ STDIO proxy to HTTP │
└──────────────────┘ └───────────┬──────────────┘
│ HTTP
▼
┌──────────────────────────┐
│ CodeWeaver Daemon │
│ (running on host) │
│ ├─ MCP Server :9328 │
│ └─ Management :9329 │
└──────────────────────────┘
For repositories with >10,000 files:
-
Configure exclude patterns in your
codeweaver.toml:[indexer] exclude_patterns = [ "node_modules", ".git", "dist", "build", "__pycache__", "*.pyc", "vendor", ".venv" ]
-
Increase container memory:
deploy: resources: limits: memory: 8G
-
Use VirtioFS on macOS Docker Desktop
Adjust result limits if needed:
# In .env
TOKEN_LIMIT=50000Check Docker resources:
docker info | grep -i memory
# Ensure at least 4GB is availableView logs:
docker compose logs codeweaver
docker compose logs qdrantVerify Qdrant is healthy:
curl http://localhost:6333/healthCheck network connectivity:
docker compose exec codeweaver curl http://qdrant:6333/healthCheck the profile and key:
# View current profile
docker compose exec codeweaver env | grep CODEWEAVER_PROFILE
# Verify API key is passed
docker compose exec codeweaver env | grep VOYAGE_API_KEYSwitch to quickstart profile (no API key needed):
CODEWEAVER_PROFILE=quickstart docker compose up -dCheck mount:
docker compose exec codeweaver ls -la /workspaceVerify exclude patterns aren't blocking your files.
Check indexer logs:
docker compose logs codeweaver | grep -i "index\|watch"If file watching isn't picking up changes:
- Check the file is in an indexed path
- Verify it's not in an exclude pattern
- Restart the container:
docker compose restart codeweaver
The container runs as user codeweaver (UID 1000). Ensure your files are readable:
# Check from inside container
docker compose exec codeweaver ls -la /workspaceRun separate instances for different projects:
# Create project-specific compose files
cp docker-compose.yml docker-compose.project1.yml
# Edit to use different:
# - Container names
# - Ports
# - Volume names
docker compose -f docker-compose.project1.yml up -dTo use Qdrant Cloud instead of the local container:
-
Set the vector deployment and URL:
VECTOR_DEPLOYMENT=cloud VECTOR_URL=https://your-cluster.cloud.qdrant.io:6333
-
Remove or comment out the
qdrantservice in docker-compose.yml -
Set your Qdrant API key:
QDRANT_API_KEY=your-qdrant-api-key
For production use:
-
Use specific version tags:
image: knitli/codeweaver:v0.1.0
-
Set resource limits:
deploy: resources: limits: cpus: '2.0' memory: 4G
-
Use secrets for API keys:
secrets: - voyage_api_key environment: - VOYAGE_API_KEY_FILE=/run/secrets/voyage_api_key
-
Enable restart policies:
restart: unless-stopped
curl http://localhost:9328/health/ | jqResponse includes:
- Service status
- Indexing progress
- Provider health
- Memory usage
docker stats codeweaver-server codeweaver-qdrant- API Keys: Never commit
.envfiles with real API keys - Network: Services communicate on internal Docker network
- User: Container runs as non-root user (
codeweaver, UID 1000) - Volumes: Codebase is mounted read-only (
:ro) - Updates: Regularly update to latest image versions
If you want to build the Docker image yourself:
# From the repository root
docker build -t codeweaver:local .
# Test the build
docker run --rm codeweaver:local codeweaver --version
# Use in docker-compose.yml
# Change: image: knitli/codeweaver:latest
# To: build: .- Resource Usage: Indexing large codebases may require significant memory
- Platform Support: Tested on linux/amd64 and linux/arm64
- CI/CD SSL Issues: Some CI environments have SSL certificate issues. Use pre-built images as a workaround. See DOCKER_BUILD_NOTES.md.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Main README
- Main README - Project overview and features
- API Reference - Generated API documentation