Procedure for standing up an Ollama model server on a Linux host — two supported paths (host install via systemd, or the official Docker image), remote-access configuration, model provisioning, memory sizing, and verification at every step.
An Ollama server is a local model backend that an Animus instance (or any OpenAI-compatible consumer) calls for inference. This SOP takes a fresh Linux host to a remotely-callable, right-sized model server.
nvidia-smi succeeds) — or accept
CPU/hybrid speeds knowingly (see sizing below)Reference points — total memory (weights + runtime overhead), measured on real hardware:
| Model | Quant / format | Total memory |
|---|---|---|
| Gemma4-31b | default | ~32 GB |
| Qwen3.6 27B | Q4KM | ~18 GB |
| Qwen3.6 27B | Q8_0 | ~30 GB |
| Qwen3.6 27B | FP16 | ~61 GB |
| DeepSeek-R1 32B | Q4KM | ~20 GB |
| DeepSeek-R1 32B | Q8_0 | ~35 GB |
| DeepSeek-R1 32B | FP16 | ~66 GB |
| GLM-5.3-Flash | native FP8 | ~306 GB |
| GLM-5.3-Flash | hybrid | ~350 GB |
Rules of thumb:
OLLAMA_MAX_LOADED_MODELS
controls how many coexist.| Path A — Host install | Path B — Docker | |
|---|---|---|
| Best when | Dedicated model box; you want systemd to own it | Shared host; you already run everything as containers |
| GPU wiring | Installer handles CUDA | Needs nvidia-container-toolkit (one-time) |
| Configuration | systemd override file | Container env vars / compose file |
| Upgrade | Re-run install script | docker pull + recreate |
Both paths end at the same place: an Ollama daemon on 11434 with models on your chosen disk. Configuration is env-var driven in both — only the delivery mechanism differs.
curl -fsSL https://ollama.com/install.sh | sh
Creates the ollama user, a systemd unit, and binds 127.0.0.1:11434.
Verify: systemctl is-active ollama → active.
curl -s http://127.0.0.1:11434/api/tags → {"models":[]} (empty list,
valid JSON).
Default is /usr/share/ollama/.ollama — often on the OS disk.
sudo systemctl stop ollama
sudo mkdir -p /data/ollama
sudo rsync -a /usr/share/ollama/.ollama/ /data/ollama/
sudo systemctl edit ollama
In the override:
[Service]
Environment="OLLAMA_MODELS=/data/ollama"
sudo systemctl daemon-reload && sudo systemctl start ollama
Verify: curl -s http://127.0.0.1:11434/api/tags still responds; pull
a small model and confirm files land under the new path.
sudo systemctl edit ollama
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_NUM_PARALLEL=2"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Firewall — allow only the consumer host, never the world:
sudo ufw allow from <consumer-ip> to any port 11434 proto tcp
Verify (from the consumer host): curl -s http://<server>:11434/api/tags
returns the model list. From any other host, the same curl must time
out.
Editing to a desired state later: add/change Environment= lines in
the override, then daemon-reload + restart ollama. The override file
is the configuration's source of truth — keep every setting there,
never in ad-hoc unit edits.
CPU-only hosts skip this step.
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Models live in the container's /root/.ollama. Bind-mount it to a
directory on your big disk (named volumes work too, but a plain directory
is inspectable and survives volume-prune):
sudo mkdir -p /opt/ollama
docker run -d --name ollama \
--restart unless-stopped \
-p 11434:11434 \
-v /opt/ollama:/root/.ollama \
--memory=24g \
ollama/ollama
--gpus all.-p 10.0.0.5:11434:11434 instead of all interfaces.--memory is prudent on shared hosts; the model budget from the
sizing table guides the value.Verify: docker ps shows Up; curl -s http://<host>:11434/api/tags
returns {"models":[]}; docker logs ollama shows the daemon listening.
On GPU hosts: docker exec ollama nvidia-smi must print the GPU table.
The configuration surface is environment variables — the same
OLLAMA_* set as Path A. Two disciplines:
Ad-hoc — recreate with new flags (state survives in the mount):
docker rm -f ollama
docker run -d --name ollama ... \
-e OLLAMA_KEEP_ALIVE=30m \
-e OLLAMA_NUM_PARALLEL=2 \
-e OLLAMA_MAX_LOADED_MODELS=1 \
ollama/ollama
Durable — keep a compose file as the source of truth (recommended; this file is the whole deployment, versionable and re-runnable):
services:
ollama:
image: ollama/ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- /opt/ollama:/root/.ollama
environment:
- OLLAMA_KEEP_ALIVE=30m
- OLLAMA_NUM_PARALLEL=2
- OLLAMA_MAX_LOADED_MODELS=1
mem_limit: 24g
# GPU hosts: uncomment
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: all
# capabilities: [gpu]
docker compose up -d # apply changes after editing
Models, the server identity keypair (id_ed25519), and CLI state persist
in the mounted directory across recreation — recreating the container is
cheap; nothing of value lives inside it.
Tuning notes (both paths):
OLLAMA_KEEP_ALIVE (default 5m) — model residency after last use.
Raise for steady traffic (no cold-start stall); 0 unloads immediately,
-1 keeps forever.OLLAMA_NUM_PARALLEL — concurrent request slots per model; each slot
costs KV-cache memory at long contexts. Default is conservative.OLLAMA_MAX_LOADED_MODELS — how many models coexist; set to what the
memory budget actually fits.Path A: sudo -u ollama ollama pull <tag>
Path B: docker exec -it ollama ollama pull <tag>
Verify: ollama list (via the same wrapper) shows exact tags —
read them carefully, they are the IDs every consumer must use. See
Common Issues for the tag-mismatch failure mode.
time curl -s http://<host>:11434/api/generate -d '{
"model": "<tag-from-ollama-list>",
"prompt": "Say ready.",
"stream": false
}'
ollama ps during/after: shows the model and its processor split
(100% GPU vs partial CPU) — the honest view of whether you're in
native or hybrid territory.Consumer gets "model not found" while ollama list shows it.
Tag mismatch. The tag the consumer configures must match ollama list
exactly — including :quant suffixes and Ollama-Cloud :cloud suffixes.
Consumers often validate model IDs against their own catalog before ever
reaching Ollama, so an ID can pass the provider API but die at the
consumer's allowlist. Fix discipline: copy the tag verbatim from
ollama list into the consumer config; when the consumer supports an
allowlist, check both gates.
First token takes forever. Cold load — the model was evicted
(OLLAMA_KEEP_ALIVE too low for the traffic pattern) or another model
took its slot (OLLAMA_MAX_LOADED_MODELS). Check ollama ps before and
during the request.
Model loads but generation crawls. Hybrid mode — weights partially or
wholly in RAM. Check the processor split in ollama ps, then pick a
smaller quant from the sizing table or add VRAM.
Load fails / process OOM-killed. Model footprint exceeds VRAM + RAM
(Path A) or the container memory limit (Path B — check docker inspect
ollama | grep OOMKilled). Drop a quant level or raise the limit.
GPU present but unused. Host layer first: nvidia-smi must work
before install; after kernel upgrades, reinstall the driver. Path B adds
a container layer: nvidia-container-toolkit installed and
nvidia-ctk runtime configure run, --gpus all present on the run —
docker exec ollama nvidia-smi discriminates host vs container failure.
journalctl -u ollama -f; Path B docker logs -f ollama.
First place to look, always.docker pull ollama/ollama + recreate — models and
identity persist in the mount.| Version | Date | Author | Description |
|---|---|---|---|
| 2 | 2026-10-14 | Animus | Procedure for standing up an Ollama model server on a Linux host — two supported paths (host install via systemd, or the official Docker image), remote-access configuration, model provisioning, memory sizing, and verification at every step. |
| 1 | 2026-10-14 | Animus | Procedure for standing up an Ollama model server on a Linux host — two supported paths (host install via systemd, or the official Docker image), remote-access configuration, model provisioning, memory sizing, and verification at every step. |