Check the install
ollama --version
systemctl status ollama # Linux install script sets up a systemd service
journalctl -u ollama -n 100 --no-pager
curl -s http://localhost:11434/api/version
The server listens on port 11434 by default. If curl fails, the server isn't running or is bound to another address (see OLLAMA_HOST below).
Docker with an NVIDIA GPU:
docker run -d --gpus=all --name ollama \
-v ollama:/root/.ollama -p 11434:11434 ollama/ollama
docker exec -it ollama ollama ps
The ollama volume keeps downloaded models across container restarts. Without it, every new container downloads the models again.
Models
| Task | Command |
|---|---|
| Download a model | ollama pull llama3.2:3b |
| List downloaded models | ollama list |
| Show details (parameters, context, quantization, license) | ollama show llama3.2:3b |
| Show the Modelfile it was built from | ollama show --modelfile llama3.2:3b |
| Chat interactively | ollama run llama3.2:3b |
| One-shot prompt | ollama run llama3.2:3b "Summarise: disk /var is 95% full" |
| Show timing and tokens/s | ollama run llama3.2:3b --verbose |
| What is loaded now, and where | ollama ps |
| Unload a model from memory | ollama stop llama3.2:3b |
| Copy / rename | ollama cp llama3.2:3b ops-assistant-base |
| Delete from disk | ollama rm llama3.2:3b |
Tags matter. llama3.2 without a tag means llama3.2:latest, which may not be the size or quantization you expect. Pin the full tag in scripts and configs.
Tip
ollama psis the first check for any performance complaint. ThePROCESSORcolumn shows100% GPU,100% CPUor a CPU/GPU split. A split means the model plus its context didn't fit in VRAM.
Inside ollama run, these slash commands help:
/set parameter num_ctx 8192
/set system "You are a terse Linux SRE. Answer with commands first."
/show info
/bye
REST API
Generate and chat
# Single prompt, no streaming
curl -s http://localhost:11434/api/generate -d '{
"model": "llama3.2:3b",
"prompt": "Explain the Linux OOM killer in two sentences.",
"stream": false
}' | jq -r .response
# Chat with roles
curl -s http://localhost:11434/api/chat -d '{
"model": "llama3.2:3b",
"messages": [
{"role": "system", "content": "Answer in one short paragraph."},
{"role": "user", "content": "What does a 502 from a load balancer usually mean?"}
],
"stream": false,
"options": {"temperature": 0, "num_ctx": 8192}
}' | jq -r .message.content
Streaming is the default. Without "stream": false you get one JSON object per line.
JSON output
curl -s http://localhost:11434/api/chat -d '{
"model": "llama3.2:3b",
"messages": [{"role": "user", "content": "Classify: \"Disk full on db01\". Return severity and team."}],
"format": {"type": "object",
"properties": {"severity": {"type": "string"}, "team": {"type": "string"}},
"required": ["severity", "team"]},
"stream": false
}' | jq -r .message.content
"format": "json" also works when you only need valid JSON and not a fixed schema. Schema support depends on your Ollama version.
Embeddings
curl -s http://localhost:11434/api/embed -d '{
"model": "nomic-embed-text",
"input": ["disk full on /var", "nginx returns 502"]
}' | jq '.embeddings | length'
Admin calls
| Call | Purpose |
|---|---|
GET /api/tags | Downloaded models (same as ollama list) |
GET /api/ps | Loaded models, memory use, expiry time |
POST /api/show with {"model": "..."} | Model details |
POST /api/pull with {"model": "..."} | Download a model |
DELETE /api/delete with {"model": "..."} | Remove a model |
GET /api/version | Server version |
Preload a model and keep it in memory, or unload it, by sending an empty request with keep_alive:
curl -s http://localhost:11434/api/generate -d '{"model": "llama3.2:3b", "keep_alive": -1}' # load, keep forever
curl -s http://localhost:11434/api/generate -d '{"model": "llama3.2:3b", "keep_alive": 0}' # unload now
OpenAI-compatible endpoint
Existing OpenAI SDK code can point at Ollama:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama") # key is required by the SDK, ignored by Ollama
r = client.chat.completions.create(
model="llama3.2:3b",
messages=[{"role": "user", "content": "Give me a one-line kubectl command to list pods not Running."}],
)
print(r.choices[0].message.content)
Compatibility covers the common chat, completions and embeddings calls, not every OpenAI feature. Test the parameters you rely on.
Modelfile: a custom model with fixed settings
Bake your system prompt and parameters into a named model so every caller gets the same behaviour:
# Modelfile
FROM llama3.2:3b
PARAMETER temperature 0.2
PARAMETER num_ctx 8192
PARAMETER stop "<|eot_id|>"
SYSTEM """
You are an on-call assistant. Answer with the command first, then one line of explanation.
If you are not sure, say so.
"""
ollama create ops-assistant -f Modelfile
ollama run ops-assistant "How do I find the biggest directories under /var?"
ollama show --modelfile ops-assistant
| Modelfile instruction | Use |
|---|---|
FROM | Base model tag, or a path to a GGUF file |
PARAMETER | Defaults such as temperature, num_ctx, top_p, stop, num_predict |
SYSTEM | Default system prompt |
TEMPLATE | Prompt template (usually inherit it from the base model) |
ADAPTER | Apply a LoRA adapter |
Keep Modelfiles in Git and rebuild with ollama create in your deployment script. That gives you a versioned, reviewable "prompt plus settings" artifact.
Server settings (environment variables)
| Variable | What it does |
|---|---|
OLLAMA_HOST | Bind address, e.g. 0.0.0.0:11434. Default is localhost only |
OLLAMA_MODELS | Where model files are stored |
OLLAMA_KEEP_ALIVE | How long an idle model stays loaded (e.g. 30m, -1 for always) |
OLLAMA_NUM_PARALLEL | Parallel requests per loaded model |
OLLAMA_MAX_LOADED_MODELS | How many models can be loaded at once |
OLLAMA_MAX_QUEUE | Queued requests before new ones are rejected |
OLLAMA_CONTEXT_LENGTH | Default context length (newer releases) |
OLLAMA_FLASH_ATTENTION | 1 to enable flash attention where supported |
OLLAMA_ORIGINS | Allowed browser origins (CORS) |
Defaults differ between releases; check journalctl -u ollama at startup, where the server prints its effective config.
On Linux with systemd, set them in an override, not in the unit file:
sudo systemctl edit ollama
[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_MODELS=/data/ollama/models"
sudo systemctl daemon-reload && sudo systemctl restart ollama
If you move OLLAMA_MODELS, the ollama service user must own the new directory (sudo chown -R ollama:ollama /data/ollama), or the server fails to start or "loses" its models.
Caution
Ollama's API has no authentication. Setting
OLLAMA_HOST=0.0.0.0exposes model pull, delete and generation to anyone who can reach the port. Keep it on localhost and put a reverse proxy with authentication and TLS in front, or restrict the port with a firewall or network security group.
Quick troubleshooting
| Symptom | Likely cause | Check / fix |
|---|---|---|
connection refused on 11434 | Service down or bound elsewhere | systemctl status ollama, check OLLAMA_HOST |
model not found | Wrong tag, or pulled into a different OLLAMA_MODELS | ollama list as the service, pin the full tag |
| First request slow, later fast | Model was unloaded after keep-alive | Raise OLLAMA_KEEP_ALIVE or preload |
| Very slow, GPU idle | Model on CPU or split | ollama ps, nvidia-smi, lower num_ctx or use a smaller quantization |
| Long prompts silently lose early text | Context smaller than the prompt | Raise num_ctx in the request or Modelfile |
| Pull fails behind a proxy | Proxy not set for the service | Add HTTPS_PROXY to the systemd override |