Why assemble this stack rather than using each tool separately
Ollama, Open WebUI and n8n are regularly cited together on r/selfhosted as the most requested combination for a complete self-hosted AI pipeline. The reason is straightforward: taken separately, each tool solves one third of the problem. Ollama exposes an OpenAI-compatible local API — but no interface for your users. Open WebUI provides that interface — but without automation. n8n orchestrates workflows — but without an embedded LLM engine, it must call an external paid API. All three together form an autonomous pipeline: inference stays on your machine, the chat is accessible from a browser, and your automations directly consume Ollama's local API via n8n's native HTTP Request node, without any third-party plugin and without per-token cost. All data — prompts, documents, conversation histories — stays in your Docker volumes, on your own infrastructure.
What the stack delivers concretely
- Private inference — Mistral 7B, Llama 3, Phi-3 or any GGUF model runs locally; no prompt ever leaves your VPS.
- Multi-user chat interface — Open WebUI exposes separate accounts, isolated histories and an endpoint compatible with Ollama's OpenAI API.
- Automation without plugins — n8n consumes
http://ollama:11434via its native HTTP Request node; the n8n.io/integrations documentation confirms no additional dependency is required. - Predictable cost — a single monthly VPS price replaces per-token fees from a cloud API; 8 GB of RAM is sufficient for Mistral 7B, Open WebUI and n8n in queue mode.
- Version control — each tool updates independently; no forced migration imposed by a SaaS vendor.
- Full portability — a
docker compose down && docker compose upis enough to migrate the stack to a more powerful VPS; Docker volumes carry all state. - Verified official Docker images —
docker.io/ollama/ollama,ghcr.io/open-webui/open-webuianddocker.io/n8nio/n8nare maintained by each respective project. - Secure internal mesh — the three services communicate over a private Docker network; no LLM port is exposed publicly.
Prerequisites: RAM, CPU and domain
RAM is the limiting factor. Ollama loaded with Mistral 7B consumes between 5 and 6 GB depending on the quantization chosen (documented in the Ollama repository). Open WebUI requires approximately 256 MB additionally. n8n in queue mode adds approximately 512 MB. The total therefore runs around 7 GB under light load, meaning an 8 GB RAM VPS handles the complete stack without active swap — a {{vps.business.name}} VPS at {{vps.business.vcpu}} vCPU and {{vps.business.ram}} is the reference profile for this configuration. For larger models (13B and above), count on 16 GB. On storage, plan at least 20 GB for Docker layers and models, more if you download several models in parallel. You will need a subdomain for each exposed service (for example chat.your-domain.com for Open WebUI and n8n.your-domain.com for n8n), Docker and Docker Compose installed, and port 443 open in your firewall.
Deploy the stack with Docker Compose
Prepare the VPS
Connect via SSH and install Docker if not already done:
curl -fsSL https://get.docker.com | sh. Verify that Docker Compose is available withdocker compose version. Create a working directory:mkdir -p /opt/ia-stack && cd /opt/ia-stack.Write the docker-compose.yml
Declare the three services in a single
docker-compose.ymlfile on a shared internal network:services: ollama: image: docker.io/ollama/ollama volumes: - ollama_data:/root/.ollama networks: - ia restart: unless-stopped open-webui: image: ghcr.io/open-webui/open-webui:main environment: - OLLAMA_BASE_URL=http://ollama:11434 volumes: - webui_data:/app/backend/data networks: - ia restart: unless-stopped n8n: image: docker.io/n8nio/n8n environment: - N8N_BASIC_AUTH_ACTIVE=true - N8N_BASIC_AUTH_USER=admin - N8N_BASIC_AUTH_PASSWORD=change-this-password - WEBHOOK_URL=https://n8n.your-domain.com volumes: - n8n_data:/home/node/.n8n networks: - ia restart: unless-stopped networks: ia: driver: bridge volumes: ollama_data: webui_data: n8n_data:No port is exposed on the host: the reverse proxy will be the only entry point.
Start the containers
Launch the stack:
docker compose up -d. Verify that all three containers are running withdocker compose ps. To view the logs of a service:docker compose logs -f ollama. At this point, no service is accessible from the outside.Download a model into Ollama
Enter the Ollama container to fetch a model:
docker compose exec ollama ollama pull mistral. The command downloads and quantizes the model into theollama_datavolume. Check the list of available models withdocker compose exec ollama ollama list. Open WebUI will automatically detect the models present in Ollama at startup.Configure the reverse proxy
Install Caddy or Nginx on the host to expose Open WebUI and n8n over HTTPS. With Caddy, two blocks suffice in your Caddyfile:
chat.your-domain.com { reverse_proxy open-webui:8080 } n8n.your-domain.com { reverse_proxy n8n:5678 }Caddy obtains and renews Let's Encrypt certificates automatically. Ollama is not exposed directly — it remains accessible only from other containers via the
ianetwork.Create the Open WebUI administrator account
Open
https://chat.your-domain.comin your browser. On first access, Open WebUI prompts you to create an administrator account (email + password). This account is local to your instance — no data transits to an external service. You can then create additional accounts from the administration interface and select a default model from those listed by Ollama.Connect n8n to the Ollama API
In n8n (
https://n8n.your-domain.com), create a workflow and add an HTTP Request node. Configure it as follows: methodPOST, URLhttp://ollama:11434/api/generate, JSON body{"model": "mistral", "prompt": "{{ $json.prompt }}", "stream": false}. n8n communicates with Ollama via the internal Docker network — no API key, no external quota. This node is native to n8n and documented on n8n.io/integrations.
Tight RAM: load the model on demand
By default, Ollama keeps the model in memory for 5 minutes after the last request, then unloads it. This behavior is configurable via the OLLAMA_KEEP_ALIVE variable. On an 8 GB VPS, setting OLLAMA_KEEP_ALIVE=0 frees RAM between scheduled n8n calls — useful if Open WebUI and n8n do not run simultaneously at full load. Conversely, OLLAMA_KEEP_ALIVE=-1 keeps the model in memory permanently for responses without loading delay.
Securing the stack before exposing it
A self-hosted AI stack handles sensitive data: prompts, workflow keys, conversation histories. Before any public exposure, verify three points. First, close Ollama's port 11434 on the host (ufw deny 11434) — it must only be accessible from the internal Docker network, never from the outside. An open LLM port exposes the generation API without authentication. Second, change the n8n authentication password in the environment variables; HTTP Basic authentication is enabled by default in the configuration above, but use a long and random password. Third, enable authentication in Open WebUI: by default, anyone reaching the URL can create an account — restrict registrations by disabling ENABLE_SIGNUP once your accounts are created. Docker volumes (ollama_data, webui_data, n8n_data) must be included in your regular backups; they contain the entire state of the stack.
VPS profiles for the stack
Scroll the table
| Profile | RAM | Recommended use case |
|---|---|---|
| VPS Start | 4 GB | Testing and development — lightweight models (Phi-3 Mini, Gemma 2B) |
| VPS Power | 8 GB | Moderate use — Mistral 7B, one or two simultaneous users |
| VPS Business | 16 GB | Full stack — Mistral 7B or Llama 3 8B, team, scheduled n8n workflows |
Use case: automating a summary pipeline with n8n
A concrete use case illustrates the value of the assembled stack. Imagine an n8n workflow triggered by a Webhook: it receives an article URL, fetches the text via an HTTP node, then sends it to Ollama for summarization. The HTTP Request node points to http://ollama:11434/api/generate with the mistral model and a prompt such as Summarize this text in 3 key points: {{$json.text}}. The response is parsed and sent to Slack, by email or stored in a database — depending on the subsequent nodes in the workflow. This type of pipeline — scraping → LLM → action — requires no external API key, runs continuously on your VPS, and consumes zero per-token cost. Other common pipelines: classifying incoming support tickets, generating product descriptions from raw spec sheets, or extracting entities from contract documents. In all these cases, the data never leaves your infrastructure. For more complex pipelines involving PDF documents or vector databases, you can add Flowise or LangFlow on the same Docker network, using Ollama as the common inference provider.
Official documentation
Each tool has its reference documentation for advanced configuration: Ollama on GitHub, Open WebUI documentation and n8n documentation. This guide covers assembly on a VPS; vendor docs remain the reference for advanced options, major updates and use cases specific to each tool.