llamaMan

llamaMan

Docker app from nullata's Repository

Overview

A browser-based UI for launching, monitoring, and managing multiple llama.cpp server instances. Spawns llama-server as sibling Docker containers using official llama.cpp images. Includes an Ollama-compatible API proxy for use with Open WebUI. Universal GPU support for NVIDIA, AMD (ROCm), Intel Arc, and CPU. Auto-detects GPU vendor at startup. Optional multi-node clustering with shared database. For full documentation, please visit: https://github.com/nullata/llamaman/

llamaMan

logo llamaMan

English · 简体中文 · 日本語 · Deutsch · Français · Español · Português · Русский

What it is. A browser UI + API front-end for running multiple llama.cpp server instances, across one machine or a small cluster of them. Ships an Ollama-compatible proxy so it drops in for Open WebUI.

What's different. llamaMan itself has no llama.cpp code and no GPU dependency - it spawns ghcr.io/ggml-org/llama.cpp:server-* containers as siblings over the Docker socket. Update llama.cpp without touching llamaMan: docker pull a newer server-* image. The same spawn-and-proxy machinery is engine-agnostic: Strata instances run alongside llama.cpp ones, launched, monitored, proxied, and slept the same way.

llama-server flag semantics are the source of truth on llama.cpp's side: server CLI reference.

Features

  • Universal GPU image - one flow for NVIDIA, AMD (ROCm), Intel Arc, CPU; vendor auto-detected (Vulkan is opt-in via GPU_TYPE=vulkan)
  • Model library + downloader - HuggingFace pulls with speed limits, resume, auto-retry, republish detection with atomic re-pull
  • One-click launch + presets - every llama.cpp knob (spec-decoding, MoE offload, KV quant, mmproj, PDF input…) is a first-class UI field, with live preset updates for fields that don't need a relaunch
  • Ollama + OpenAI proxy on :42069 - Open WebUI drops in; models auto-start on demand and LRU-evict once LLAMAMAN_MAX_MODELS is hit
  • Image & PDF input - vision models with --mmproj; PDFs rasterized page-by-page
  • Instance monitoring - per-GPU VRAM, container CPU/RAM, per-instance TTFT / throughput / latency
  • Auth - user accounts, API keys (bearer tokens), per-endpoint auth toggle
  • Multi-node clustering (opt-in) - heterogeneous nodes as one logical cluster; aggregated dashboard; shared-queue load balancing
  • 🆕 Strata engine (opt-in, NVIDIA) - launch Strata instances next to llama.cpp ones
  • 🆕 Knowledge base + MCP server (opt-in, MariaDB backend) - store documents as topics, search them by meaning with your own embedding model, and expose the whole thing to any MCP client — all local

Requirements

Quick Start

Edit docker-compose.yml first:

  • Set HOST_MODELS_DIR / HOST_LOGS_DIR to the real host paths that back your volume mounts (llamaMan passes them to the Docker daemon when spawning sibling containers).
  • LLAMAMAN_NODE_NAME (srv1 in the sample compose; there is no built-in default - the app refuses to start without it) is required for every install - it's the partition key for this deployment's stored state. Pick once, keep it (changing later orphans stored state).

Pull the llama.cpp image for your GPU and start:

GPU LLAMA_IMAGE
NVIDIA ghcr.io/ggml-org/llama.cpp:server-cuda
AMD (ROCm) ghcr.io/ggml-org/llama.cpp:server-rocm
Intel Arc ghcr.io/ggml-org/llama.cpp:server-sycl
Vulkan (AMD/Intel fallback) ghcr.io/ggml-org/llama.cpp:server-vulkan (set GPU_TYPE=vulkan)
CPU only ghcr.io/ggml-org/llama.cpp:server
docker pull <LLAMA_IMAGE>          # from the table above
# For non-CUDA: also set LLAMA_IMAGE=... in docker-compose.yml
docker compose up --build

For NVIDIA native VRAM monitoring, also uncomment deploy.resources.reservations in docker-compose.yml.

Security note: the mounted /var/run/docker.sock gives the container full control of Docker on the host. Standard Docker-socket-access implications apply.

Running bare-metal (dev, WSL)? See Running bare-metal.

Your first model

  1. Get a model. Either drop a .gguf into your models directory, or open the UI, pick a HuggingFace repo under Downloads, and let llamaMan pull it.
  2. Launch it. Select the model in the sidebar, click Launch. llamaMan spawns a llama-server container and the instance appears with a status badge. Defaults (4096 ctx, auto GPU layers) work for most models; Save Preset remembers your settings. Every launch field is documented in Launch settings.
  3. Create an API key. Under API Keys, create one (llm-xxxxxxxxxx). Model endpoints require a bearer token by default.
  4. Point your client at it. Any OpenAI or Ollama client works against :42069. For Open WebUI:
open-webui:
  environment:
    - OLLAMA_BASE_URL=http://llamaman:42069
    - OPENAI_API_BASE_URLS=http://llamaman:42069/v1
    - OPENAI_API_KEYS=llm-your-api-key-here

Open WebUI lists your models via /api/tags (by GGUF filename stem unless you set a Display Name); picking one auto-starts it, waits until healthy, then proxies. Set a per-model Display Name to show a friendly name instead of the raw quant filename.

Cap caveat: the sample compose ships LLAMAMAN_MAX_MODELS=1. With a cap set, the Ollama connection evicts the LRU model when full, but the OpenAI connection (OPENAI_API_BASE_URLS) returns 503 by default - pick one path or raise the cap. Rules: Model Eviction.

If something goes wrong, Troubleshooting below covers the common first-run failures.

Authentication

Two credential types:

  • Session cookies for the UI (created via /setup on first launch)
  • API keys for external clients (Authorization: Bearer llm-xxxxxxxxxx), managed under API Keys in the UI

The "Require authentication for all endpoints" toggle (on by default) controls whether model-serving endpoints demand a bearer token. Details: Authentication.

Architecture

llamaMan is a small Python app that never touches llama.cpp code directly. It spawns each llama-server as a sibling container over the Docker socket, monitors the fleet, and hands out an OpenAI/Ollama front door.

%%{init: {'theme': 'base', 'themeVariables': {'fontFamily': 'ui-sans-serif, system-ui, sans-serif', 'fontSize': '14px', 'primaryColor': '#eef2ff', 'primaryBorderColor': '#6366f1', 'primaryTextColor': '#1e1b4b', 'lineColor': '#64748b', 'clusterBkg': '#f8fafc', 'clusterBorder': '#cbd5e1', 'edgeLabelBackground': '#f8fafc'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 40, 'rankSpacing': 60}}}%%
flowchart LR
  client[Client<br/>Open WebUI / any OpenAI or Ollama client]

  subgraph nodeA[Node A]
    lmA[llamaman<br/>:5000 UI · :42069 compat]
    subgraph workersA[llama-server siblings on host GPUs]
      wA1[qwen2.5-14b]
      wA2[gpt-oss-20b]
    end
  end

  subgraph nodeB[Node B]
    lmB[llamaman]
    subgraph workersB[llama-server siblings]
      wB1[qwen2.5-14b]
      wB2[deepseek-v3]
    end
  end

  db[(Shared storage<br/>presets · instance state · heartbeats)]

  client -->|prompt| lmA
  lmA -->|forward when a peer is less loaded| lmB
  lmA --> wA1
  lmA --> wA2
  lmB --> wB1
  lmB --> wB2
  lmA <-.-> db
  lmB <-.-> db

  classDef core fill:#4f46e5,stroke:#312e81,color:#fff
  classDef worker fill:#0d9488,stroke:#134e4a,color:#fff
  classDef ext fill:#64748b,stroke:#334155,color:#fff
  class lmA,lmB core
  class wA1,wA2,wB1,wB2 worker
  class client,db ext

The single-node picture (default) is just the top half - one llamaman container, N llama-server siblings on the local Docker daemon, no cluster peers, JSON files instead of the shared DB. Clustering is opt-in and additive.

How it works in depth - request flow, queue-aware dispatch, failure behavior, design trade-offs: Architecture.

Documentation

Guide What's in it
Launch settings Every launch-form field and its llama-server flag: ctx, KV cache, GPU layers, MoE offload, spec decoding, sampling overrides, concurrency & queueing, live preset updates, Image & PDF input, Anti-Loop, per-instance proxy, idle timeout
Models Display names, model updates, Decision Models (/v1/systemone), Model Eviction, download settings, Docker image management, model archive, backup & restore, cleanup
Configuration & storage Bare-metal installs, auth detail, GPU stats, request recording, JSON vs MariaDB backends, surviving a DB outage, and the full Environment Variables reference
Clustering Multi-node setup: shared DB, heartbeats, shared-queue load balancing
Knowledge Base & MCP Topics, embeddings, MCP endpoint, access modes
Strata The second inference engine: setup, catalogue, limits, design notes
REST API Core endpoints: instances, downloads, presets, settings, request log, launch-body quirks
Troubleshooting The full symptom → fix table

Environment Variables

The ones you'll touch on day one (full reference: Environment Variables):

Variable Default Description
LLAMAMAN_NODE_NAME (required) Unique stable identity - pick once, keep it
HOST_MODELS_DIR / HOST_LOGS_DIR (= container paths) Real host paths behind the volume mounts
LLAMA_IMAGE (auto) llama.cpp image; auto-selected from GPU vendor, set to pin. The sample compose pins server-cuda - change it for non-NVIDIA GPUs
LLAMAMAN_MAX_MODELS 0 Max concurrent chat models via the proxy (LRU eviction; 0 = unlimited). The sample compose sets 1
DATABASE_URL (unset) MariaDB/MySQL connection string. Unset = JSON files

Troubleshooting

Symptom Fix
Instance stuck on starting Check logs via the Logs button. Common: OOM, model path typo, corrupt GGUF, image not pulled
"Docker image not found" Pull the matching image: docker pull ghcr.io/ggml-org/llama.cpp:server-cuda (or server-rocm / server-sycl / server)
"Docker API error" on launch Ensure /var/run/docker.sock is mounted (default in docker-compose.yml)
No GPU / CUDA error Ensure NVIDIA Container Toolkit is installed and docker run --gpus all works on the host
GPU stats unavailable NVIDIA: uncomment the deploy.resources.reservations block. AMD/Intel: ensure /sys/class/drm:ro is mounted
Model not showing in OpenWebUI Ensure OLLAMA_BASE_URL=http://llamaman:42069. Check /api/tags returns models
OpenWebUI gets 401 require_auth is on (default). Create an API key and set OPENAI_API_KEYS in OpenWebUI
OpenAI client gets 503 when models are full LLAMAMAN_MAX_MODELS cap reached and the OpenAI API can't evict by default. Raise the cap or enable the eviction toggles: Model Eviction
Port conflict The form auto-suggests an unused port; adjust if needed

Full table: Troubleshooting.

Credits

This work would not be possible without ggml-org/llama.cpp.

License

llamaMan is licensed under the Elastic License 2.0. You may use, copy, distribute, and modify the software, subject to:

  • No providing the software to third parties as a hosted / managed service where the service gives users access to a substantial set of its features or functionality.
  • No removing or obscuring licensing, copyright, or other notices of the licensor.

Third-party licenses

Download Statistics

7,587
Total Downloads

Related apps

Explore more like this

Explore all

Details

Repository
nullata/llamaman
Last Updated2026-10-12
First Seen2026-07-28

Runtime arguments

Web UI
http://[IP]:[PORT:5000]
Network
bridge
Shell
sh
Privileged
false
Extra Params
--publish 8000-8020:9000-9020

Template configuration

Management UI PortPorttcp

Port for the llamaMan management web UI

Target
5000
Default
5000
Value
5000
Proxy PortPorttcp

Ollama-compatible API proxy port (for OpenWebUI integration)

Target
42069
Default
42069
Value
42069
ModelsPath

Directory containing GGUF model files

Target
/models
Default
/mnt/user/appdata/llamaman/models
Value
/mnt/user/appdata/llamaman/models
DataPath

Persistent data directory (state, presets, users, settings)

Target
/data
Default
/mnt/user/appdata/llamaman/data
Value
/mnt/user/appdata/llamaman/data
LogsPath

Directory for instance and download logs

Target
/tmp/llama-logs
Default
/mnt/user/appdata/llamaman/logs
Value
/mnt/user/appdata/llamaman/logs
Docker SocketPath

Docker socket — required for llamaMan to spawn llama-server containers

Target
/var/run/docker.sock
Default
/var/run/docker.sock
Value
/var/run/docker.sock
GPU Sysfs (AMD/Intel)Pathro

GPU monitoring via sysfs (AMD + Intel Arc). Safe on NVIDIA hosts — ignored when pynvml is available.

Target
/sys/class/drm
Default
/sys/class/drm
Value
/sys/class/drm
TZVariable

Timezone. List of available TZs: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

Default
Europe/Sofia
Value
Europe/Sofia
LLAMAMAN_NODE_NAMEVariable

**Required.** Unique, stable identity for this deployment. It is the partition key for instances, downloads, and per-node settings. Pick once and keep it — changing it later orphans stored state.

Default
srv1
Value
srv1
HOST_MODELS_DIRVariable

Real host path to the models directory. llamaMan passes this to the Docker daemon when spawning sibling containers, so it must resolve on the host. **Must match the host path of the Models mount above** — if you change one, change both.

Default
/mnt/user/appdata/llamaman/models
Value
/mnt/user/appdata/llamaman/models
HOST_LOGS_DIRVariable

Real host path to the logs directory. Same requirement as HOST_MODELS_DIR — must resolve on the Docker host. **Must match the host path of the Logs mount above.**

Default
/mnt/user/appdata/llamaman/logs
Value
/mnt/user/appdata/llamaman/logs
LLAMAMAN_MAX_MODELSVariable

Maximum number of chat models the proxy keeps loaded simultaneously. 0 = disabled (no eviction, launches on demand).

Default
1
Value
1
LLAMAMAN_PROXY_PORTVariable

Internal proxy port (must match the Proxy Port config above)

Default
42069
Value
42069
LLAMAMAN_IDLE_TIMEOUTVariable

Minutes of inactivity before proxy-managed instances are stopped. 0 = disabled.

Default
0
Value
0
HEALTH_CHECK_TIMEOUTVariable

Seconds to wait for a llama-server container health check before timing out

Default
3
Value
3
MODEL_LOAD_TIMEOUTVariable

Seconds to wait for a model to fully load before timing out

Default
300
Value
300
REQUEST_TIMEOUTVariable

Seconds before a proxied inference request times out

Default
300
Value
300
LLAMA_IMAGEVariable

llama.cpp server image for spawned containers. Auto-detected from GPU vendor if unset. NVIDIA: ghcr.io/ggml-org/llama.cpp:server-cuda AMD ROCm: ghcr.io/ggml-org/llama.cpp:server-rocm Intel Arc: ghcr.io/ggml-org/llama.cpp:server-sycl CPU: ghcr.io/ggml-org/llama.cpp:server

Default
ghcr.io/ggml-org/llama.cpp:server-cuda
Value
ghcr.io/ggml-org/llama.cpp:server-cuda
LLAMA_NETWORKVariable

Docker network used by llamaMan and spawned containers

Default
llamaman-net
Value
llamaman-net
LLAMA_CONTAINER_PREFIXVariable

Prefix for spawned llama-server container names

Default
llamaman-
Value
llamaman-
GPU_TYPEVariable

Override GPU auto-detection. Values: cuda, rocm, intel. Leave blank to auto-detect.

LLAMA_GPU_DEVICESVariable

Comma-separated GPU indices visible to all llama-server containers (e.g. 0,1,3). Leave blank to expose all GPUs.

NVIDIA_VISIBLE_DEVICESVariable

NVIDIA hosts only — set to 'all' (or a specific GPU UUID) to give the llamaMan container native VRAM monitoring (pynvml). Also requires '--runtime=nvidia' in Extra Parameters and NVIDIA_DRIVER_CAPABILITIES below, plus the Unraid Nvidia-Driver plugin. Leave blank on AMD/Intel/CPU hosts — GPU stats then fall back to nvidia-smi/rocm-smi inside a running instance.

NVIDIA_DRIVER_CAPABILITIESVariable

NVIDIA hosts only — set to 'utility' for native VRAM monitoring. Pairs with NVIDIA_VISIBLE_DEVICES and '--runtime=nvidia' in Extra Parameters. Leave blank on AMD/Intel/CPU hosts.

DATABASE_URLVariable

Optional MariaDB/MySQL connection string for database backend. Example: mysql+pymysql://llamaman:password@host:3306/llamaman. Leave blank for JSON file storage (default).

SECRET_KEYVariable

Flask session secret. Required for multi-replica deployments. Leave blank for auto-generated per restart.

CLUSTER_ENABLEDVariable

Enable multi-node clustering. Set to true when running multiple llamaMan deployments as one cluster. Requires shared DATABASE_URL and CLUSTER_SECRET.

CLUSTER_SECRETVariable

Shared bearer token for node-to-node HTTP calls. Must be identical on every cluster node.

CLUSTER_ADVERTISE_URLVariable

How peers reach this node (e.g. http://srv1:5000). A hostname/IP routable from other cluster hosts.