issues/completed/10-017-multi-ollama-server-configuration.md
Issue 10-017: Multi-Ollama Server Configuration
Priority: Medium
Phase: 10 (Developer Experience & Tooling)
Status: Completed
Completed: 2026-01-30
Created: 2026-01-30
Summary
Add support for multiple Ollama server configurations, allowing users to define several servers with different models and switch between them via TUI or CLI.
Current Behavior
Ollama configuration is scattered and implicit:
OLLAMA_HOSTenvironment variable (or defaultlocalhost:11434)- Model name passed via CLI flags or hardcoded
- No centralized server configuration
This makes it difficult to:
- Switch between local and remote Ollama instances
- Use different models for different runs
- Share configuration across team members
Intended Behavior
1. Config Section for Ollama Servers
Add an ollama_servers section to config.lua:
-- {{{ ollama_servers
-- Define available Ollama servers for embedding generation.
-- The pipeline will use the server selected in the TUI or via --ollama flag.
-- At least one server must be defined. First server is the default.
ollama_servers = {
{
name = "local", -- Label shown in TUI
description = "Local Ollama instance",
host = "localhost",
port = 11434,
model = "nomic-embed-text", -- Default embedding model
-- Optional: alternative models available on this server
available_models = {
"nomic-embed-text",
"mxbai-embed-large",
"all-minilm"
}
},
{
name = "gpu-server",
description = "Remote GPU server for faster embeddings",
host = "192.168.0.115",
port = 11434,
model = "nomic-embed-text",
available_models = {
"nomic-embed-text",
"mxbai-embed-large"
}
},
{
name = "gpu-server-alt",
description = "Remote GPU server (alternate port)",
host = "192.168.0.115",
port = 10265,
model = "mxbai-embed-large"
}
},
-- }}}
2. TUI Selection in run.sh
Add Ollama server selection to the pipeline configuration menu:
┌─────────────────────────────────────────────────────────────────────────────┐
│ Pipeline Configuration │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Ollama Server: │
│ (●) local - Local Ollama instance (nomic-embed-text) │
│ ( ) gpu-server - Remote GPU server (nomic-embed-text) │
│ ( ) gpu-server-alt - Remote GPU server alternate (mxbai-embed-large) │
│ │
│ Select stages to run: │
│ ... │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Selection behavior:
- Radio button selection (exactly one must be selected)
- First server in config is selected by default
- Shows name, description, and current model
- Cannot deselect all (minimum one required)
3. CLI Flag Override
# Use specific server by name
./run.sh --ollama gpu-server
# Override model for the selected server
./run.sh --ollama gpu-server --model mxbai-embed-large
# List available servers
./run.sh --list-ollama
4. Environment Variable Construction
The selected server config constructs the OLLAMA_HOST environment variable:
-- From config
local server = selected_ollama_server
local ollama_host = string.format("http://%s:%d", server.host, server.port)
-- Set environment for child processes
os.execute(string.format("export OLLAMA_HOST='%s'", ollama_host))
Files to Update
| File | Changes |
|---|---|
config.lua | Add ollama_servers section |
run.sh | Add TUI selection, --ollama flag, server list display |
scripts/generate-embeddings.lua | Read server config, use selected server |
src/centroid-generator.lua | Use selected Ollama server |
libs/ollama-client.lua | Accept server config object (if exists) |
| Any script calling Ollama | Update to use centralized config |
Implementation Steps
Step 1: Add Config Section
Add ollama_servers to config.lua with at least one default server.
Step 2: Create Server Loader
-- libs/ollama-config.lua
local M = {}
function M.get_servers()
local config = require("config-loader").load()
return config.ollama_servers or {
-- Fallback default
{name = "local", host = "localhost", port = 11434, model = "nomic-embed-text"}
}
end
function M.get_server_by_name(name)
for _, server in ipairs(M.get_servers()) do
if server.name == name then
return server
end
end
return nil
end
function M.get_default_server()
local servers = M.get_servers()
return servers[1]
end
function M.build_host_url(server)
return string.format("http://%s:%d", server.host, server.port)
end
return M
Step 3: Update run.sh TUI
Add radio button selection for Ollama servers before stage selection.
Step 4: Update Embedding Scripts
-- In generate-embeddings.lua
local ollama_config = require("ollama-config")
-- Get server from CLI arg or use default
local server_name = arg_parser.get("--ollama") or nil
local server = server_name
and ollama_config.get_server_by_name(server_name)
or ollama_config.get_default_server()
if not server then
error("Ollama server not found: " .. (server_name or "(default)"))
end
local ollama_host = ollama_config.build_host_url(server)
local model = arg_parser.get("--model") or server.model
print("Using Ollama server: " .. server.name .. " (" .. ollama_host .. ")")
print("Model: " .. model)
Step 5: Validate Configuration
At pipeline start, verify the selected Ollama server is reachable:
function M.validate_server(server)
local url = M.build_host_url(server) .. "/api/tags"
local handle = io.popen(string.format("curl -s -o /dev/null -w '%%{http_code}' '%s'", url))
local status = handle:read("*a")
handle:close()
return status == "200"
end
TUI Implementation Details
Radio Button Behavior
-- Menu items for Ollama selection
local ollama_items = {}
for i, server in ipairs(ollama_servers) do
table.insert(ollama_items, {
id = "ollama_" .. server.name,
label = server.name .. " - " .. server.description .. " (" .. server.model .. ")",
type = "radio",
group = "ollama", -- All in same radio group
selected = (i == 1), -- First is default
value = server.name
})
end
-- Radio group constraint: exactly one selected
-- When user selects one, deselect others in same group
function select_radio(items, selected_id, group)
for _, item in ipairs(items) do
if item.group == group then
item.selected = (item.id == selected_id)
end
end
end
Display Format
Ollama Server:
(●) local - Local Ollama instance (nomic-embed-text)
( ) gpu-server - Remote GPU server for faster embeddings (nomic-embed-text)
( ) gpu-server-alt - Remote GPU server (mxbai-embed-large)
Success Criteria
- [x]
ollama_serversconfig section with name, host, port, model - [ ] TUI radio button selection for Ollama server (deferred - CLI sufficient for current needs)
- [x] First server is default, exactly one must be selected
- [x] CLI
--ollama NAMEflag to select server - [x] CLI
--model NAMEflag to override model - [x] CLI
--list-ollamato show available servers - [x] All embedding scripts use selected server config
- [x] Server validation at pipeline start (reachable check)
- [x] Graceful error if selected server is unreachable
Related Files
config.lua- Main configuration filerun.sh- Pipeline runner with TUIscripts/generate-embeddings.lua- Primary embedding generationsrc/centroid-generator.lua- Centroid embedding generationissues/completed/1-002-configure-ollama-embedding-service.md- Original Ollama setupissues/completed/1-005-standardize-ollama-port-configuration.md- Port standardization
Notes
- The
available_modelsfield is optional - for future model selection UI - Consider adding a "test connection" button in TUI
- Server validation should be quick (timeout after 2-3 seconds)
- If validation fails, show warning but allow user to proceed (server might come online)
- Store last-used server in a session file for convenience (optional enhancement)
Implementation Notes (2026-01-30)
Files Modified
| File | Changes |
|---|---|
config.lua | Added ollama_servers section (lines 275-318) with gpu-server, gpu-server-alt, and local servers |
libs/ollama-config.lua | Complete rewrite with new API: get_servers(), get_server_by_name(), get_default_server(), get_selected_server(), set_selected_server(), build_host_url(), validate_server(), list_servers() |
run.sh | Added --ollama NAME, --model NAME, --list-ollama flags; added server validation before embedding stages |
generate-embeddings.sh | Added --ollama flag support, updated endpoint setup to use ollama-config |
libs/fuzzy-computing.lua | Migrated from OLLAMA_ENDPOINT to build_host_url() |
src/generate-word-pages.lua | Migrated from OLLAMA_ENDPOINT to build_host_url() |
src/centroid-generator.lua | Migrated from OLLAMA_ENDPOINT to build_host_url() |
src/similarity-engine.lua | Migrated from OLLAMA_ENDPOINT to build_host_url() |
src/ollama-manager.lua | Migrated from OLLAMA_ENDPOINT to build_host_url() |
Design Decisions
- No Fallbacks: Removed all backward-compatibility code (
OLLAMA_ENDPOINT,detect_ollama_endpoint(),get_ollama_endpoint()). Code should error clearly if config is missing, not silently use defaults.
- CLI-First: Deferred TUI radio button selection. The
--ollama,--model, and--list-ollamaCLI flags provide sufficient control for current workflow.
- Server Validation: Added validation check before embedding stages 3/4/6 to fail-fast if selected server is unreachable.
- Centralized Config: All Ollama server definitions now live in
config.luawith a clean API inlibs/ollama-config.lua.
Lessons Learned
- Backward-compatibility fallbacks create "stale code branches" - better to migrate all usages and remove the fallback entirely.
- The
set_project_root()pattern in ollama-config allows the module to work from any directory by deferring config loading until needed.