-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdocker-compose.cuda.yml
More file actions
131 lines (130 loc) · 7.06 KB
/
Copy pathdocker-compose.cuda.yml
File metadata and controls
131 lines (130 loc) · 7.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
services:
code-index-api:
image: dvcdsys/code-index:cu128
# No container_name on purpose. A fixed name is global to the docker
# daemon, so a second cix on the same host (a Portainer stack, another
# clone, a re-run from a different directory) dies with "the container
# name /code-index is already in use". Compose's own
# <project>-<service>-1 naming keeps them side by side; ask for the real
# name with `docker compose ps` when a command needs it.
restart: unless-stopped
ports:
- "${PORT:-21847}:21847"
environment:
- CIX_API_KEY=${CIX_API_KEY}
# Defense in depth — the image already defaults to 21847 but
# pinning it here keeps the host:container port mapping honest
# if a third-party fork or custom build sets a different default.
- CIX_PORT=${CIX_PORT:-21847}
- CIX_EMBEDDING_MODEL=${CIX_EMBEDDING_MODEL:-awhiteside/CodeRankEmbed-Q8_0-GGUF}
# Legacy chromem-go store: read once on startup for the one-time import
# into the SQLite vector store, then left untouched as the rollback path.
- CIX_CHROMA_PERSIST_DIR=/data/chroma
# Optional. Vector store: one SQLite database per embedding namespace.
# Defaults to a sibling of CIX_CHROMA_PERSIST_DIR (/data/vectors), so it
# already lands on the volume below — set it only to move the vectors to
# a different mount.
# - CIX_VECTORS_DIR=/data/vectors
# Optional. PRAGMA mmap_size for the vector store, in bytes; 0 (default)
# is off. Roughly 40% lower search latency in exchange for resident
# memory — mapped database pages count in RSS, per connection. There is
# room for it under the 10G limit below on a GPU host.
# - CIX_VECTOR_MMAP_SIZE=2147483648
- CIX_SQLITE_PATH=/data/sqlite/projects.db
- CIX_MAX_FILE_SIZE=${CIX_MAX_FILE_SIZE:-524288}
- CIX_EXCLUDED_DIRS=${CIX_EXCLUDED_DIRS:-node_modules,.git,.venv,__pycache__,dist,build,.next,.cache,.DS_Store}
- CIX_N_GPU_LAYERS=99
# GGUF cache lives on the named volume below — survives `docker compose
# down` (without -v) and is owned by the image's 1001:1001 user, so the
# cix-server process can always write to it regardless of host
# bind-mount permissions.
- CIX_GGUF_CACHE_DIR=/data/models
- CIX_LLAMA_BIN_DIR=/app
- CIX_LLAMA_STARTUP_TIMEOUT=120
- CIX_EMBEDDINGS_ENABLED=${CIX_EMBEDDINGS_ENABLED:-true}
# ── First-boot admin seed (required when the DB has no users yet) ──
# cix-server refuses to start when the users table is empty AND these
# are unset. Set BOTH in your .env, log in once, change the password
# immediately (the user is flagged must_change_password=true).
- CIX_BOOTSTRAP_ADMIN_EMAIL=${CIX_BOOTSTRAP_ADMIN_EMAIL:-}
- CIX_BOOTSTRAP_ADMIN_PASSWORD=${CIX_BOOTSTRAP_ADMIN_PASSWORD:-}
# ── PR-E runtime tunables (all DB-overridable from /dashboard/server) ──
# 0 = auto. Threads → runtime.NumCPU()/2; batch → match n_ctx.
- CIX_LLAMA_THREADS=${CIX_LLAMA_THREADS:-0}
- CIX_LLAMA_BATCH=${CIX_LLAMA_BATCH:-0}
# Embedding queue parallelism. Default 5 (was 1) — pipelines host-side
# prep with device inference. Drop to 1 if you observe contention.
- CIX_MAX_EMBEDDING_CONCURRENCY=${CIX_MAX_EMBEDDING_CONCURRENCY:-5}
- CIX_EMBEDDING_QUEUE_TIMEOUT=${CIX_EMBEDDING_QUEUE_TIMEOUT:-300}
# Optional: skip the first-boot HF download by pointing at a GGUF
# file the operator already has on disk. cix copies it into the
# cix-models named volume once (atomic .partial → rename) and never
# touches the source again. Subsequent boots find the file in cache
# and ignore the env. See volumes block below for an example bind.
- CIX_BOOTSTRAP_GGUF_PATH=${CIX_BOOTSTRAP_GGUF_PATH:-}
# ── Pluggable embedding providers (added in migration 12) ──
# The active provider is selected from the dashboard
# (/dashboard/server → Embedding provider). On first boot with an
# empty runtime_settings row, cix-server seeds the ollama provider
# using the CIX_EMBEDDING_MODEL + CIX_LLAMA_* vars above — so the
# default deployment is unchanged.
#
# To use a remote provider (OpenAI-compatible or Voyage AI) you
# MUST export the API-key env var below. The dashboard reads it on
# every embed call; cix-server NEVER persists API keys in the DB,
# only the env-var NAME a provider should look up. Switching
# providers triggers a full reindex per project on the next clone
# job (existing model-change pipeline).
#
# OpenAI-compatible (api.openai.com, vLLM, TEI, LocalAI, …):
# - CIX_OPENAI_API_KEY=${CIX_OPENAI_API_KEY:-}
#
# Voyage AI:
# - CIX_VOYAGE_API_KEY=${CIX_VOYAGE_API_KEY:-}
- NVIDIA_VISIBLE_DEVICES=all
volumes:
# Operator-managed bind for sqlite + chroma so backups and inspection
# are one `cd` away on the host. On Linux the directory must be owned
# by 1001:1001 (`sudo chown -R 1001:1001 ~/.cix/data`) or the server
# cannot create its database; `user: "0:0"` is the less safe fallback.
# install-server.sh does the chown for you. See doc/TEAM_DEPLOYMENT.md.
- ${HOME}/.cix/data:/data
# Docker-managed named volume layered ON TOP of /data/models. This
# isolates the GGUF cache from host-side bind permission issues and
# guarantees the model is downloaded exactly once across container
# recreates (`docker compose up --force-recreate`, image bumps, etc.).
- cix-models:/data/models
# Optional bootstrap: bind a host-side .gguf read-only into
# /bootstrap/model.gguf and set CIX_BOOTSTRAP_GGUF_PATH=/bootstrap/model.gguf
# in your .env. cix imports it into the cix-models cache on first boot,
# then ignores both the env and the bind. After verifying the cache is
# seeded, the bind can be removed entirely.
# - /srv/hf-cache/coderankembed-q8_0.gguf:/bootstrap/model.gguf:ro
deploy:
resources:
limits:
memory: 10G
reservations:
memory: 2G
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
# /health only answers once the whole boot is done — llama model load
# (minutes from cold) and, on the first start after an upgrade, the
# one-time chromem -> SQLite vector-store import. Failures inside
# start_period do not count, so this window is simply "how long before a
# slow boot may be called broken". Nothing acts on `unhealthy` here
# (restart: unless-stopped reacts to exits, not health), so an over-long
# window costs nothing, while a short one paints the container red mid-boot
# and invites a restart that throws the boot away.
healthcheck:
test: ["CMD", "/cix-server", "-healthcheck"]
interval: 30s
timeout: 10s
start_period: 600s
retries: 3
volumes:
cix-models:
# GGUF model cache. Persisted by Docker; only `docker compose down -v`
# (or explicit `docker volume rm <project>_cix-models`) wipes it.