Module 8 — Integrating with existing applications
The runtime is installed (module 1), the right model is pulled and tuned (modules 2 to 6), the GPU is doing its job (module 7). This module plugs Ollama into the tools the firm already uses — a Python case-management helper, LangChain for the retrieval pipeline of module 9, and Open WebUI as the chat interface — and covers the one topic no article about local models discusses seriously enough: safely opening the service to other machines on the network.
Calling from a business script
The simplest integration is a Python function that the case-management tool already imports. It receives a piece of contract text and a question and returns a factual paragraph:
from ollama import Client
client = Client(host="http://127.0.0.1:11434")
def ask_firm_assistant(context: str, question: str) -> str:
resp = client.chat(
model="firm-fr", # the derived tag from module 5
messages=[
{"role": "system", "content": "Answer only from the provided context. If the answer is not there, say so."},
{"role": "user", "content": f"Context:\n{context}\n\nQuestion: {question}"},
],
options={"temperature": 0, "num_ctx": 8192, "num_predict": 512},
)
return resp["message"]["content"]
Two decisions in these ten lines are the ones production code should never move around. The temperature is fixed at zero because a case-management tool re-runs the same question after a re-save and users demand the same answer. The system prompt narrows the model's job to "answer from the given context" — the retrieval layer (module 9) is what feeds context, and this line closes the door on the model inventing anything outside it.
Calling from LangChain
Course 26 taught LangChain in depth. The one-line integration is:
from langchain_ollama import ChatOllama
llm = ChatOllama(
model="firm-fr",
base_url="http://127.0.0.1:11434",
temperature=0,
num_ctx=8192,
)
Every downstream primitive from that course — chains, retrievers, memory, tools, agents — works against this llm unchanged. The Runnable interface is what makes swapping providers a one-line change: a chain written in a prototype against ChatOpenAI moves to ChatOllama by replacing the constructor, and the tests keep passing.
For embeddings, the companion class:
from langchain_ollama import OllamaEmbeddings
embed = OllamaEmbeddings(model="nomic-embed-text", base_url="http://127.0.0.1:11434")
Module 9 assembles both into a full offline RAG pipeline on the firm's PDFs.
Adding Open WebUI
Open WebUI is a self-hosted chat interface that speaks the OpenAI API and can be pointed at Ollama's compatibility endpoint. It gives associates a browser-based ChatGPT-style UI that never talks to any cloud. The recommended install is Docker:
docker run -d --name openwebui \
-p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-e OPENAI_API_BASE_URL=http://host.docker.internal:11434/v1 \
-e OPENAI_API_KEY=ollama \
-v openwebui:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main
The associates browse to http://server.firm.local:3000, sign in with their firm email, pick firm-fr from the model dropdown, and start chatting. History, user accounts, per-user rate limits and RAG uploads live in the volume openwebui. The Ollama runtime knows nothing about users — Open WebUI is the layer that maps a browser session to a request.
Exposing the runtime to the LAN
By default, Ollama binds to 127.0.0.1:11434 — no other machine can reach it. To let Open WebUI on the server serve associates on their laptops, one option is to run the container on the same server as Ollama (as above, via host.docker.internal) and only expose the WebUI's port 3000. That is the recommended shape: the runtime stays private, the UI does the network work.
If for some reason another host must reach Ollama directly (a script on a different machine, a second WebUI on a workstation), open the port carefully. Three steps in order:
- Set
OLLAMA_HOST=0.0.0.0:11434on the service (via the environment on Linux, the tray settings on Windows), restart it. - Restrict access at the firewall: only the office subnet, never the internet.
- Put a reverse proxy with authentication in front — Caddy, nginx or Traefik. A minimal Caddyfile:
ollama.firm.local {
reverse_proxy 127.0.0.1:11434
basicauth {
associates $2a$14$...bcrypt-hash...
}
}
Ollama itself has no built-in authentication. Exposing port 11434 to a public network without a proxy is equivalent to publishing your inference budget for anyone to spend. It is the single most common mistake in first deployments.
Timeouts, retries and keep-alive
A production integration handles three timing realities. The first request after a model load takes seconds; subsequent ones are fast. A client should set the HTTP timeout to at least 120 seconds on the first call. OLLAMA_KEEP_ALIVE=30m avoids reloading between two spaced requests. On the client side, retry a 503 (model still loading) with a short back-off, and surface a 500 out of memory as a hard error instead of retrying — the second try will fail the same way.
Neither the native API nor the OpenAI-compatible endpoint checks credentials. Any host that can reach the port can use the model, and can list, pull and delete tags. Always front the service with a proxy that authenticates, and never leave it on 0.0.0.0 without a firewall rule limiting the subnet.
Summary
- A Python client with
Client(host=...)covers the simplest business integration; pintemperatureandnum_ctxat the call site. - LangChain exposes
ChatOllamaandOllamaEmbeddings; a chain written against another provider swaps to Ollama by replacing the constructor. - Open WebUI in Docker gives associates a browser-based chat that speaks the OpenAI-compatible endpoint and holds user accounts.
- Ollama has no authentication; expose the port only through a reverse proxy with basic auth and a firewall rule.
Next module: the retrieval layer — local embeddings, a local vector index, and a fully offline document Q&A over the firm's archive.