Files
LLM-Server/docker-compose.yml
T

166 lines
5.3 KiB
YAML

services:
llama-server:
image: ghcr.io/ggml-org/llama.cpp:server-rocm
container_name: llama-server
devices:
- /dev/kfd
- /dev/dri
# see docs/architecture.md#gpu-access (group_add GIDs, GPU_MAX_HW_QUEUES)
group_add:
- "${HOST_VIDEO_GID:?run scripts/update.sh first to resolve this}"
- "${HOST_RENDER_GID:?run scripts/update.sh first to resolve this}"
security_opt:
- seccomp=unconfined
ipc: host
environment:
- GPU_MAX_HW_QUEUES=1
volumes:
- models:/models
command: >
-m /models/${LLAMA_MODEL_FILE:-Qwen3.8-27B-UD-Q4_K_XL.gguf}
--host 0.0.0.0
--port 8080
--n-gpu-layers ${LLAMA_GPU_LAYERS:-999}
--ctx-size ${LLAMA_CTX_SIZE:-262144}
--parallel ${LLAMA_PARALLEL:-2}
--kv-unified
--flash-attn on
--cache-type-k q8_0
--cache-type-v q8_0
--cache-reuse 256
--spec-type draft-mtp
--spec-draft-n-max 2
--jinja
# see docs/architecture.md#llama-server (flags), docs/network-access.md#backends (no host port)
expose:
- "8080"
restart: unless-stopped
networks: [ai-stack]
# see docs/architecture.md#qwen-classifier
qwen-classifier:
image: ghcr.io/ggml-org/llama.cpp:server-rocm
container_name: qwen-classifier
devices:
- /dev/kfd
- /dev/dri
group_add:
- "${HOST_VIDEO_GID:?run scripts/update.sh first to resolve this}"
- "${HOST_RENDER_GID:?run scripts/update.sh first to resolve this}"
security_opt:
- seccomp=unconfined
ipc: host
# see docs/architecture.md#gpu-access
environment:
- GPU_MAX_HW_QUEUES=1
volumes:
- models:/models
command: >
-m /models/${LLAMA_CLASSIFIER_MODEL_FILE:-Qwen3-4B-Instruct-2507-UD-Q4_K_XL.gguf}
--host 0.0.0.0
--port 8080
--n-gpu-layers 28
--ctx-size 50000
--parallel 1
--batch-size 512
--ubatch-size 128
--flash-attn on
--reasoning off
--cache-type-k q4_0
--cache-type-v q4_0
--jinja
expose:
- "8080"
restart: unless-stopped
networks: [ai-stack]
# see docs/operations.md#model-downloads (also covers downloader-classifier)
downloader:
image: curlimages/curl:latest
profiles: ["tools"]
user: root
volumes:
- models:/models
entrypoint: ["sh", "-c"]
command:
- >
test -f /models/${LLAMA_MODEL_FILE:-Qwen3.8-27B-UD-Q4_K_XL.gguf} &&
echo "already downloaded, skipping" ||
curl -L --fail --create-dirs -o /models/${LLAMA_MODEL_FILE:-Qwen3.8-27B-UD-Q4_K_XL.gguf}
https://huggingface.co/unsloth/Qwen3.8-27B-GGUF/resolve/main/${LLAMA_MODEL_FILE:-Qwen3.8-27B-UD-Q4_K_XL.gguf}
downloader-classifier:
image: curlimages/curl:latest
profiles: ["tools"]
user: root
volumes:
- models:/models
entrypoint: ["sh", "-c"]
command:
- >
test -f /models/${LLAMA_CLASSIFIER_MODEL_FILE:-Qwen3-4B-Instruct-2507-UD-Q4_K_XL.gguf} &&
echo "already downloaded, skipping" ||
curl -L --fail --create-dirs -o /models/${LLAMA_CLASSIFIER_MODEL_FILE:-Qwen3-4B-Instruct-2507-UD-Q4_K_XL.gguf}
https://huggingface.co/unsloth/Qwen3-4B-Instruct-2507-GGUF/resolve/main/${LLAMA_CLASSIFIER_MODEL_FILE:-Qwen3-4B-Instruct-2507-UD-Q4_K_XL.gguf}
# see docs/architecture.md#omniroute; runtime config lives in its dashboard, see docs/gateway.md
omniroute:
image: diegosouzapw/omniroute:latest
container_name: omniroute
depends_on:
llama-server:
condition: service_started
volumes:
- omniroute-data:/app/data
env_file: .env
environment:
- API_HOST=0.0.0.0
- API_PORT=${OMNIROUTE_API_PORT:-20129}
- DASHBOARD_PORT=${OMNIROUTE_DASHBOARD_PORT:-20128}
# Security: relaxes OmniRoute's SSRF guard — see docs/gateway.md#provider-connections
- OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true
- OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS=true
- OMNIROUTE_WS_BRIDGE_SECRET=${OMNIROUTE_WS_BRIDGE_SECRET}
- OMNIROUTE_MEMORY_MB=8192
# see docs/gateway.md#timeouts (both timeouts below)
- STREAM_IDLE_TIMEOUT_MS=${OMNIROUTE_STREAM_IDLE_TIMEOUT_MS:-180000}
- REQUEST_TIMEOUT_MS=${OMNIROUTE_REQUEST_TIMEOUT_MS:-1800000}
# see docs/gateway.md#web-search
extra_hosts:
- "search.home:${SEARXNG_LAN_IP}"
ports:
- "${OMNIROUTE_API_PORT:-20129}:${OMNIROUTE_API_PORT:-20129}"
- "${OMNIROUTE_DASHBOARD_PORT:-20128}:${OMNIROUTE_DASHBOARD_PORT:-20128}"
mem_limit: 10g
# Don't shorten: SQLite needs it to checkpoint its WAL, or recent writes are lost — see docs/architecture.md#omniroute
stop_grace_period: 40s
restart: unless-stopped
networks: [ai-stack]
healthcheck:
test:
- CMD-SHELL
- node -e "require('net').connect(${OMNIROUTE_API_PORT:-20129},'localhost').on('connect',function(){this.end();process.exit(0)}).on('error',()=>process.exit(1))"
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# see docs/architecture.md#qdrant, docs/network-access.md#qdrant
qdrant:
image: qdrant/qdrant:latest
container_name: qdrant
volumes:
- qdrant-data:/qdrant/storage
ports:
- "127.0.0.1:6333:6333"
restart: unless-stopped
networks: [ai-stack]
networks:
ai-stack:
volumes:
models:
omniroute-data:
qdrant-data: