Deployment guide

Hosting Ollama on a VPS: advanced operational guide

Deploy on a VPS Cloud →

Artificial Intelligence10 min read

Hosting Ollama on a VPS: advanced operational guide

Once Ollama is running on your VPS, the real work begins: choosing models suited to your RAM, securing the API behind a reverse proxy, maintaining performance as updates roll in, and integrating the inference engine into your stack. This guide covers the operational angle — everything after the first `docker run` — including CVE-2026-45672, which affects Open WebUI coupled with Ollama, and the steps to secure that coupling.

Ollama in production: what changes after the first start

Deploying Ollama takes a few minutes. Running it reliably over time takes more attention. In production, three points concentrate most of the problems: model management (which to load, which to remove to free disk space), the API attack surface (unauthenticated by default on port 11434), and memory usage (an oversized model saturates RAM and gets killed by the kernel). This guide assumes the ollama container is already running and focuses on these three areas, plus integration with your stack tools.

What advanced management brings in practice

  • Selective pull — you download only the model you need, without filling the disk with unused variants.
  • Clean removalollama rm frees disk space and reduces the load time of remaining models.
  • Documented REST API — Ollama exposes /api/generate, /api/chat and /v1/chat/completions; a reverse proxy in front gives an HTTPS endpoint with authentication.
  • Controlled concurrencyOLLAMA_MAX_LOADED_MODELS prevents several models from loading simultaneously and exhausting the RAM.
  • Persistent environment variablesOLLAMA_KEEP_ALIVE, OLLAMA_NUM_THREADS and OLLAMA_CONTEXT_SIZE are injected into the docker run or in a versioned compose.yml.
  • Scriptable model rotation — a simple curl call to /api/pull is enough to automate model updates from a CI pipeline.
  • Selective exposure — you can expose the API only to your internal tools (Open WebUI, n8n, LangFlow) without making it public.

Choosing and managing models: size, RAM and quantization

A model's size is expressed in billions of parameters (B) and determines the RAM required. A 1B/3B model fits in 2 to 3 GB and suits simple tasks (classification, short summary) on a modest VPS. A 7B/8B requires 5 to 6 GB in Q4: this is the most common quality/resource ratio. A 13B needs 9 to 10 GB, and a 70B exceeds 40 GB — reserved for high-memory VPS or GPU configurations. For each size, quantization adjusts the quality/speed trade-off: Q4_K_M offers a good quality/speed balance on CPU, Q8 preserves more precision at the cost of doubled RAM. Before pulling a model, check free space with df -h and available RAM with free -h.

Common operations: pull, removal and API exposure

01

List available models

Run docker exec ollama ollama list to see already downloaded models, their disk size and the date they were added.

02

Download a new model

Run docker exec ollama ollama pull llama3.2:3b for a lightweight model, or docker exec ollama ollama pull qwen2.5:7b-instruct-q4_K_M for a quantized 7B. The q4_K_M suffix specifies the quantization directly in the tag.

03

Remove an old model

Free up space with docker exec ollama ollama rm llama3.1:8b. Verify afterwards with docker exec ollama ollama list that the model no longer appears.

04

Test the REST API locally

Call the chat endpoint: curl http://127.0.0.1:11434/api/chat -d '{"model":"qwen2.5:7b-instruct-q4_K_M","messages":[{"role":"user","content":"Ping"}],"stream":false}'. The JSON response contains the message.content field.

05

Configure environment variables

Restart the container with the desired options: docker run -d -v ollama:/root/.ollama -p 127.0.0.1:11434:11434 -e OLLAMA_KEEP_ALIVE=-1 -e OLLAMA_MAX_LOADED_MODELS=1 -e OLLAMA_NUM_THREADS=4 --name ollama ollama/ollama. These parameters keep the model in memory and limit CPU load.

06

Apply a rate-limit via nginx

In your nginx server block, add limit_req_zone $binary_remote_addr zone=ollama:10m rate=10r/m; in the http section, then limit_req zone=ollama burst=5 nodelay; in the location. This protects the API from repeated burst calls.

07

Update Ollama itself

Stop and remove the container: docker stop ollama && docker rm ollama. Pull the new image: docker pull ollama/ollama. Restart with the same parameters. Models are stored in the ollama volume and are not affected.

08

Check service health

Run curl http://127.0.0.1:11434/api/tags to get the list of loaded models. An HTTP 200 with valid JSON confirms the service is responding correctly.

Ollama behind an nginx reverse proxy with a token

By default, Ollama listens on 127.0.0.1:11434 without authentication. To expose it to your tools (Open WebUI, n8n, a remote script), place nginx as a front end with a Bearer token. The configuration block below delegates access to a secret token defined in the $api_token variable, checks the Authorization header and proxies to Ollama. CORS is configured to accept requests from your interface without exposing the API to all origins.

In /etc/nginx/sites-available/ollama:

map $http_authorization $api_token_valid {
    default 0;
    "Bearer YOUR_SECRET_TOKEN" 1;
}
server {
    listen 443 ssl;
    server_name api-ia.your-domain.com;
    ssl_certificate /etc/letsencrypt/live/api-ia.your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api-ia.your-domain.com/privkey.pem;
    location / {
        if ($api_token_valid = 0) { return 401; }
        proxy_pass http://127.0.0.1:11434;
        proxy_set_header Host $host;
        add_header Access-Control-Allow-Origin "https://ui.your-domain.com";
    }
}

Activate with ln -s /etc/nginx/sites-available/ollama /etc/nginx/sites-enabled/ then nginx -t && systemctl reload nginx.

CPU performance: choosing the right quantization

On CPU, Q4_K_M is the recommended balance point: marginal quality loss compared to Q8, with approximately 40% faster generation speed and half the memory usage. Reserve Q8 for cases where precision is critical (code, formal logic) and your VPS has at least 16 GB of free RAM. Adjust OLLAMA_NUM_THREADS to the number of physical cores (not logical) to avoid contention: on a 4 vCPU VPS, start at 3. The OLLAMA_CONTEXT_SIZE parameter (default: 2048 tokens) directly affects RAM per request; reduce it if you handle many short calls in parallel.

Troubleshooting: the most common cases

Four situations come up regularly in production.

Model too slow. Generation exceeds 2-3 tokens per second on CPU for a 7B? Check that OLLAMA_NUM_THREADS is not at 1 (default if not set on some images). Also check that only one model is loaded (OLLAMA_MAX_LOADED_MODELS=1): two simultaneous models compete for cores and memory bandwidth.

Insufficient VRAM (GPU). If the Docker log shows CUDA out of memory or ROCm error, the model does not fit in VRAM. Switch to the q4_K_M tag or reduce OLLAMA_CONTEXT_SIZE. Ollama falls back to CPU if VRAM is insufficient, but without clearly indicating it: compare generation speeds to detect this.

API connection refused. curl: (7) Failed to connect from outside while the service is listening? The firewall is blocking port 11434, or nginx is not started. Check with ss -tlnp | grep 11434 (should show 127.0.0.1, not 0.0.0.0) and systemctl status nginx.

Signal killed / OOM. The process is killed by the kernel (OOM killer). The VPS RAM is insufficient for the selected model. Switch to a smaller size or enable a 4 to 8 GB swap as a buffer: fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile. Swap slows generation but avoids brutal stops.

Integration with other VPS tools

Ollama is a backend: it takes its full value when other services connect to it. Three tools integrate naturally on the same VPS.

Open WebUI exposes a conversation interface similar to ChatGPT, connected to the local Ollama API. In its environment file, set OLLAMA_BASE_URL=http://ollama:11434 (if both containers share a Docker network) or OLLAMA_BASE_URL=http://127.0.0.1:11434 if Open WebUI runs on the same host. Open WebUI handles model selection, conversation history and user management. Note: the Ollama ↔ Open WebUI coupling exposes an additional attack surface — see the CVE-2026-45672 section below.

LangFlow is a visual LLM pipeline builder. Add an Ollama node to your flow, enter http://127.0.0.1:11434 as the base URL and select the model from the dropdown. LangFlow calls the /api/generate endpoint directly without internal authentication — place it on the VPS private network, not exposed publicly.

n8n lets you trigger Ollama calls from an automation workflow. Use the HTTP Request node pointing to http://127.0.0.1:11434/api/chat with a JSON body containing model and messages. From n8n, you can chain an Ollama call to a data retrieval step, email send or outgoing webhook without writing code.

CVE-2026-45672: authorization bypass in Open WebUI

Published on May 21, 2026 (GHSA-482j-2pq6-q5w4), this vulnerability affects all versions of Open WebUI prior to 0.8.12. CVSS score: 8.8 (high).

Attack mechanics. An authenticated user can execute arbitrary Python code via the /api/v1/utils/code/execute endpoint, even if the administrator has disabled code execution in settings (ENABLE_CODE_EXECUTION=false). The guard is declared in the configuration but is never enforced at the API layer: any verified account on the instance can trigger execution.

Impact. The attacker gains access to the underlying Jupyter backend and can read arbitrary files on the VPS, steal secrets (API keys, Ollama Bearer token, environment variables), or establish persistence. The confidentiality, integrity and availability of the server are compromised.

Why this is critical in an Ollama ↔ Open WebUI coupling. Ollama and Open WebUI often run on the same VPS, sometimes in the same Docker network, with shared secrets (fallback OpenAI API key, Ollama API Bearer token). An RCE on Open WebUI therefore gives direct access to the Ollama API and models in memory, bypassing the reverse proxy entirely.

Fix. Update Open WebUI to version 0.8.12 or later. This version enforces the ENABLE_CODE_EXECUTION check at the API endpoint level, where it should always have been.

Check your version. From the container: docker exec open-webui cat /app/package.json | grep '"version"'. If the output is below 0.8.12, the update is urgent: docker pull ghcr.io/open-webui/open-webui:main && docker stop open-webui && docker rm open-webui then restart with the same environment parameters.

Hardening the Ollama ↔ Open WebUI coupling after CVE-2026-45672

Four additional measures to apply after updating to 0.8.12.

1. Isolate Docker networks. Create a dedicated bridge network (docker network create llm-private) and place both containers on it. Ollama is then only reachable from Open WebUI via the service name (http://ollama:11434), without going through the VPS public interface.

2. Never expose port 11434 externally. Confirm the binding stays on 127.0.0.1:11434. On the internal Docker network, Ollama responds on port 11434 without authentication — this is acceptable if the network is private; it becomes a vector as soon as it is accessible from outside.

3. Disable code execution if you do not need it. In Open WebUI environment variables, set ENABLE_CODE_EXECUTION=false. After updating to 0.8.12, this setting is finally enforced at the API level. If your use case does not include code execution, disable it as a defense-in-depth measure.

4. Restrict registrations. In the Open WebUI admin interface (Settings → Administration), disable public sign-ups (ENABLE_SIGNUP=false) if the instance is exposed to the Internet. CVE-2026-45672 requires a verified account: reducing the sign-up surface reduces the attack surface.

Your private LLM server on a ServOrbit Cloud VPS

The ServOrbit Cloud VPS provides the RAM and scalability needed to run your Ollama models in production. Scale resources as you move to larger models, with no migration or downtime.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.