feat: support physical and Docker Ollama runtimes

This commit is contained in:
Hermes Agent
2026-08-24 20:22:22 +10:00
parent 9f2be5b368
commit 7def2990ce
5 changed files with 95 additions and 5 deletions
+25
View File
@@ -57,6 +57,31 @@ https://gitea.beyondcloud.solutions/dennii/Hermes-Ollama_Models.git
In Hermes Dashboard, open **Plugins**, choose **Install from repository**, enter the URL above, and install. The repository contains the root `plugin.yaml`, dashboard manifest, backend API, compiled frontend bundle, stylesheet, and an opt-in prerequisite declaration. On Linux, the Hermes installer will verify Ollama, install it with the official Ollama installer when missing, and install the plugin's `pypdf` dependency before committing the plugin into `~/.hermes/plugins/`. Ollama installation requires the Hermes container to run as root, which is the expected configuration for a privileged ZimaOS deployment. If the container is not running as root, the plugin install stops without enabling a partially configured plugin. After installation or an update, restart only the Hermes dashboard service if requested by the installer. In Hermes Dashboard, open **Plugins**, choose **Install from repository**, enter the URL above, and install. The repository contains the root `plugin.yaml`, dashboard manifest, backend API, compiled frontend bundle, stylesheet, and an opt-in prerequisite declaration. On Linux, the Hermes installer will verify Ollama, install it with the official Ollama installer when missing, and install the plugin's `pypdf` dependency before committing the plugin into `~/.hermes/plugins/`. Ollama installation requires the Hermes container to run as root, which is the expected configuration for a privileged ZimaOS deployment. If the container is not running as root, the plugin install stops without enabling a partially configured plugin. After installation or an update, restart only the Hermes dashboard service if requested by the installer.
## Physical and Docker deployments
The plugin supports both deployment types:
- **Physical/Linux Hermes:** Ollama defaults to `http://localhost:11434`. If Ollama is missing, the prerequisite installer can install it on a root-run host.
- **Docker Hermes:** Ollama should normally run as a separate service or on the Docker host. The plugin does not install Ollama inside the Hermes container. Set `OLLAMA_HOST` to the reachable Ollama base URL, without `/v1`, for example `http://ollama:11434` for a Compose service or `http://host.docker.internal:11434` for a host service.
For host access on Linux Docker, add this to the Hermes service when needed:
```yaml
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
OLLAMA_HOST: http://host.docker.internal:11434
```
For Compose service-to-service networking, use the Ollama service name instead:
```yaml
environment:
OLLAMA_HOST: http://ollama:11434
```
The dashboard plugin API is mounted when the dashboard starts. Restart Hermes after installing or enabling the plugin; otherwise the plugin page can load while `/api/plugins/ollama-manager/status` still returns 404.
## Security limits ## Security limits
- Uploaded files are limited to 20 MiB each - Uploaded files are limited to 20 MiB each
+1 -1
View File
@@ -3,7 +3,7 @@
"label": "Ollama Models", "label": "Ollama Models",
"description": "Inspect, manage, and chat with local Ollama models, including shared persistent conversations, performance metrics, images, PDFs, URLs, and live memory telemetry.", "description": "Inspect, manage, and chat with local Ollama models, including shared persistent conversations, performance metrics, images, PDFs, URLs, and live memory telemetry.",
"icon": "Cpu", "icon": "Cpu",
"version": "1.5.2", "version": "1.5.3",
"tab": {"path": "/ollama-manager", "position": "after:models"}, "tab": {"path": "/ollama-manager", "position": "after:models"},
"entry": "dist/index.js", "entry": "dist/index.js",
"css": "dist/style.css", "css": "dist/style.css",
+28 -2
View File
@@ -31,7 +31,20 @@ from pydantic import BaseModel, Field
from hermes_constants import get_hermes_home from hermes_constants import get_hermes_home
router = APIRouter() router = APIRouter()
LOCAL_OLLAMA = os.environ.get("OLLAMA_HOST", "http://localhost:11434").rstrip("/")
def _running_in_container() -> bool:
return Path("/.dockerenv").exists() or Path("/run/.containerenv").exists()
def _ollama_base_url() -> str:
configured = os.environ.get("OLLAMA_HOST", "").strip()
if configured:
return configured.rstrip("/")
return "http://ollama:11434" if _running_in_container() else "http://localhost:11434"
LOCAL_OLLAMA = _ollama_base_url()
REMOTE_OLLAMA = "https://ollama.com" REMOTE_OLLAMA = "https://ollama.com"
CATALOG_FILE = "catalog.json" CATALOG_FILE = "catalog.json"
MODEL_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:/-]{0,190}$") MODEL_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:/-]{0,190}$")
@@ -1396,8 +1409,21 @@ def status() -> dict[str, Any]:
variants.append(variant) variants.append(variant)
row["variants"] = sorted(variants, key=lambda item: (item.get("size_bytes") or 0, item["name"])) row["variants"] = sorted(variants, key=lambda item: (item.get("size_bytes") or 0, item["name"]))
ollama_version = _ollama_version()
return { return {
"ollama": {"available": bool(tags or ps_rows), "version": _ollama_version(), "endpoint": LOCAL_OLLAMA}, "ollama": {
"available": bool(tags or ps_rows or ollama_version),
"version": ollama_version,
"endpoint": LOCAL_OLLAMA,
"containerized": _running_in_container(),
"configured_endpoint": bool(os.environ.get("OLLAMA_HOST", "").strip()),
"connection_hint": (
"Set OLLAMA_HOST to a reachable Ollama service, such as "
"http://ollama:11434 or http://host.docker.internal:11434."
if _running_in_container() and not (tags or ps_rows or ollama_version)
else ""
),
},
"models": local, "models": local,
"popular": popular, "popular": popular,
"popular_filter": { "popular_filter": {
+2 -2
View File
@@ -1,10 +1,10 @@
name: ollama-manager name: ollama-manager
version: 1.5.2 version: 1.5.3
description: Native dashboard manager and chat interface for local Ollama models, attachments, URLs, shared persistent conversations, performance metrics, and live runtime telemetry. description: Native dashboard manager and chat interface for local Ollama models, attachments, URLs, shared persistent conversations, performance metrics, and live runtime telemetry.
auto_install_dependencies: true auto_install_dependencies: true
python_dependencies: python_dependencies:
- "pypdf>=6.0,<7.0" - "pypdf>=6.0,<7.0"
external_dependencies: external_dependencies:
- name: Ollama - name: Ollama
check: ollama --version check: bash scripts/install_ollama.sh --check
install: bash scripts/install_ollama.sh install: bash scripts/install_ollama.sh
+39
View File
@@ -7,6 +7,45 @@ if [[ "$(uname -s)" != "Linux" ]]; then
exit 1 exit 1
fi fi
is_container() {
if [[ -f /.dockerenv ]]; then
return 0
fi
[[ -f /run/.containerenv ]]
}
ollama_endpoint() {
if [[ -n "${OLLAMA_HOST:-}" ]]; then
printf '%s' "${OLLAMA_HOST%/}"
elif is_container; then
printf '%s' 'http://ollama:11434'
else
printf '%s' 'http://localhost:11434'
fi
}
check_endpoint() {
command -v curl >/dev/null 2>&1 || return 1
curl --fail --silent --show-error --max-time 5 "$(ollama_endpoint)/api/version" >/dev/null
}
if [[ "${1:-}" == "--check" ]]; then
if command -v ollama >/dev/null 2>&1 && ! is_container; then
ollama --version >/dev/null
exit 0
fi
check_endpoint
exit $?
fi
if is_container; then
if check_endpoint; then
exit 0
fi
printf '%s\n' 'Docker/container runtime detected. Configure OLLAMA_HOST to a reachable Ollama service (for example http://ollama:11434 or http://host.docker.internal:11434); Hermes will not install Ollama inside its own container.' >&2
exit 1
fi
if command -v ollama >/dev/null 2>&1; then if command -v ollama >/dev/null 2>&1; then
ollama --version >/dev/null ollama --version >/dev/null
exit 0 exit 0