Shared embedding service for ava-brain and mc-brain on pico. One model
loaded in RAM, served over the internal Docker network. Auto-unloads after
idle to protect server headroom.
- Base:
ollama/ollama:latest - Model:
dengcao/Qwen3-Embedding-0.6B:F16(1024-dim, ~600MB) - API: OpenAI-compatible
/v1/embeddingsat port 8080 - Auto-unload: 5 minutes idle → model unloaded from RAM (
OLLAMA_KEEP_ALIVE=5m) - First request after unload: ~5 s warmup, then fast
| Path | Auth | Purpose |
|---|---|---|
POST /v1/embeddings | none (private network) | OpenAI-compatible embedding API. Used by brain-core's embeddings module. |
GET /api/tags | none | Healthcheck. Lists loaded models. |
POST /api/pull | none | Pull a new model into the persistent volume. |
Models live in a Docker named volume (embedder-models), NOT on the encrypted LUKS vault. Public model weights aren't sensitive — the encrypted vault is only for PGLite data and audit logs.
embedder-models (Docker volume) → /root/.ollama
└── models/ (qwen3 weights, ~600 MB)
Both ava-brain and mc-brain reach the embedder on the shared Docker network:
BRAIN_EMBED_URL=http://embedder:8080/v1
BRAIN_EMBED_MODEL=dengcao/Qwen3-Embedding-0.6B:F16
BRAIN_EMBED_DIM=1024
(set in each brain's Coolify env)
brain-core also has a reranker path (BRAIN_RERANKER_URL → /v1/rerank).
Ollama doesn't natively expose this endpoint. brain-core/rerank.js already
falls back gracefully when the reranker fails — search still works without
it, just slightly less precise. Future improvement: add a second container
for the rerank model behind /v1/rerank if precision becomes a felt gap.
docker compose up --build
curl -X POST http://localhost:8080/v1/embeddings \
-H 'Content-Type: application/json' \
-d '{"model":"dengcao/Qwen3-Embedding-0.6B:F16","input":["hello world"]}'| jq '.data[0].embedding | length'# Should print: 1024- New Coolify "Application" sourced from this repo
- Network: attach to the shared
brain-netDocker network - Volume: bind a named volume
embedder-modelsto/root/.ollama - Port: do not expose to host — internal-only on
brain-net - Resources: limit to 1.5 CPU / 1.5 GB RAM on Coolify
| State | RAM |
|---|---|
| Idle (model unloaded) | ~50 MB (just Ollama runtime) |
| Loaded (after a request) | ~700 MB (Ollama + qwen3 0.6B) |
| Peak (during inference) | ~900 MB |
The auto-unload means pico's other services aren't starved during quiet periods.
Because we're switching from llama.cpp+qwen3 (local) to Ollama+Qwen3-Embedding-0.6B (hosted), existing embeddings in pgvector are from a different model variant and won't be directly comparable. After Phase E migration, run once per brain:
# From inside the brain container (or via Coolify exec)
node embed-all.js --forceThis re-embeds every embedded row against the new model. Takes ~10 min per brain on cold-start.