Manage Ollama setup for homelab host
This commit is contained in:
parent
172bcca975
commit
5504dd7b2e
|
|
@ -853,6 +853,15 @@ other nodes can reach `OLLAMA_HOST=http://192.168.100.73:11434`:
|
|||
./jeannie website-ollama-listen
|
||||
```
|
||||
|
||||
The Debian host bootstrap also manages Ollama when `debian_pc_install_ollama`
|
||||
is true: it installs the service, stores models under `/data/ollama/models`,
|
||||
binds the API to the configured LAN listener, and pulls the lightweight
|
||||
`ai_gateway.model`. On an existing host, apply just this setup with:
|
||||
|
||||
```bash
|
||||
./jeannie ollama-setup
|
||||
```
|
||||
|
||||
`jeannie` also has a backstage local AI helper for doctor commands.
|
||||
It is not a separate CLI action; when `ai_gateway.enabled` is true in
|
||||
`homelab.yml`, doctor commands try the configured Ollama model and silently
|
||||
|
|
|
|||
|
|
@ -853,6 +853,15 @@ other nodes can reach `OLLAMA_HOST=http://192.168.100.73:11434`:
|
|||
./{{ main_script }} website-ollama-listen
|
||||
```
|
||||
|
||||
The Debian host bootstrap also manages Ollama when `debian_pc_install_ollama`
|
||||
is true: it installs the service, stores models under `/data/ollama/models`,
|
||||
binds the API to the configured LAN listener, and pulls the lightweight
|
||||
`ai_gateway.model`. On an existing host, apply just this setup with:
|
||||
|
||||
```bash
|
||||
./{{ main_script }} ollama-setup
|
||||
```
|
||||
|
||||
`{{ main_script }}` also has a backstage local AI helper for doctor commands.
|
||||
It is not a separate CLI action; when `ai_gateway.enabled` is true in
|
||||
`homelab.yml`, doctor commands try the configured Ollama model and silently
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ The playbook:
|
|||
- installs user-level pipx CLI tools such as `yt-dlp`, plus runtime helpers
|
||||
such as `ffmpeg` and `nodejs`
|
||||
- installs `age` and `sops` for encrypted repo-managed secrets
|
||||
- installs and configures Ollama for homelab-local AI helpers when
|
||||
`debian_pc_install_ollama` is true
|
||||
- installs Zoom from the upstream `.deb` when requested on amd64
|
||||
- adds `jv` to expected local groups
|
||||
- enables core services such as Docker, containerd, kubelet, ssh, cron, and
|
||||
|
|
@ -48,3 +50,13 @@ After the playbook finishes, initialize the Debian host's SOPS identity with:
|
|||
./jeannie secrets-init
|
||||
./jeannie secrets-check
|
||||
```
|
||||
|
||||
Ollama is configured to listen on the LAN and keep models under
|
||||
`/data/ollama/models`. The default lightweight model for `jeannie` diagnostics is
|
||||
pulled during bootstrap. To apply only the Ollama setup on an existing Debian
|
||||
host, run:
|
||||
|
||||
```bash
|
||||
./jeannie ollama-setup
|
||||
./jeannie ai-check
|
||||
```
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@ debian_pc_user: jv
|
|||
debian_pc_user_home: "/home/{{ debian_pc_user }}"
|
||||
debian_pc_kubernetes_minor_version: v1.36
|
||||
debian_pc_enable_passwordless_sudo: true
|
||||
debian_pc_install_ollama: true
|
||||
debian_pc_ollama_install_url: https://ollama.com/install.sh
|
||||
debian_pc_ollama_host: 0.0.0.0:11434
|
||||
debian_pc_ollama_models_dir: /data/ollama/models
|
||||
debian_pc_ollama_default_model: qwen2.5:0.5b
|
||||
|
||||
debian_pc_persistent_directories:
|
||||
- /data/openebs/local/registry
|
||||
- /data/docker
|
||||
- /data/ollama/models
|
||||
- "/home/{{ debian_pc_user }}/git-server"
|
||||
- "/home/{{ debian_pc_user }}/backups/gitea"
|
||||
- "/home/{{ debian_pc_user }}/backups/gitea-restore-drills"
|
||||
|
|
|
|||
|
|
@ -229,6 +229,54 @@
|
|||
mode: "{{ '0755' if item.startswith(debian_pc_user_home) else '0775' }}"
|
||||
loop: "{{ debian_pc_persistent_directories }}"
|
||||
|
||||
- name: Check whether Ollama is already installed
|
||||
ansible.builtin.shell:
|
||||
cmd: command -v ollama >/dev/null 2>&1
|
||||
register: debian_pc_ollama_installed
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Install Ollama from official Linux installer
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
tmp_installer="$(mktemp)"
|
||||
trap 'rm -f "${tmp_installer}"' EXIT
|
||||
curl -fsSL "{{ debian_pc_ollama_install_url }}" -o "${tmp_installer}"
|
||||
sh "${tmp_installer}"
|
||||
args:
|
||||
executable: /bin/bash
|
||||
when:
|
||||
- debian_pc_install_ollama | bool
|
||||
- debian_pc_ollama_installed.rc | default(1) != 0
|
||||
|
||||
- name: Ensure Ollama model storage exists on data disk
|
||||
ansible.builtin.file:
|
||||
path: "{{ debian_pc_ollama_models_dir }}"
|
||||
state: directory
|
||||
owner: ollama
|
||||
group: ollama
|
||||
mode: "0775"
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Ensure Ollama systemd override directory exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/system/ollama.service.d
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Configure Ollama for homelab LAN access and data storage
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/systemd/system/ollama.service.d/homelab.conf
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Service]
|
||||
Environment="OLLAMA_HOST={{ debian_pc_ollama_host }}"
|
||||
Environment="OLLAMA_MODELS={{ debian_pc_ollama_models_dir }}"
|
||||
register: debian_pc_ollama_override
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Enable expected services when installed
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ item }}"
|
||||
|
|
@ -237,6 +285,42 @@
|
|||
loop: "{{ debian_pc_enable_services }}"
|
||||
failed_when: false
|
||||
|
||||
- name: Enable and start Ollama
|
||||
ansible.builtin.systemd:
|
||||
name: ollama
|
||||
enabled: true
|
||||
state: "{{ 'restarted' if debian_pc_ollama_override.changed | default(false) else 'started' }}"
|
||||
daemon_reload: true
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Wait for Ollama API
|
||||
ansible.builtin.uri:
|
||||
url: http://127.0.0.1:11434/api/tags
|
||||
method: GET
|
||||
status_code: 200
|
||||
register: debian_pc_ollama_api
|
||||
retries: 12
|
||||
delay: 5
|
||||
until: debian_pc_ollama_api.status == 200
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Pull default Ollama model for backstage homelab diagnostics
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
if ollama list | awk -v model="{{ debian_pc_ollama_default_model }}" 'NR > 1 && ($1 == model || $1 == model ":latest") { found = 1 } END { exit found ? 0 : 1 }'; then
|
||||
echo present
|
||||
exit 0
|
||||
fi
|
||||
ollama pull "{{ debian_pc_ollama_default_model }}"
|
||||
echo pulled
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: debian_pc_ollama_pull_result
|
||||
changed_when: "'pulled' in debian_pc_ollama_pull_result.stdout"
|
||||
environment:
|
||||
OLLAMA_HOST: http://127.0.0.1:11434
|
||||
when: debian_pc_install_ollama | bool
|
||||
|
||||
- name: Check whether config archive is present
|
||||
ansible.builtin.stat:
|
||||
path: "{{ debian_pc_config_archive }}"
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ services:
|
|||
ollama:
|
||||
host: debian
|
||||
url: http://192.168.100.73:11434
|
||||
bind_address: 0.0.0.0:11434
|
||||
models_dir: /data/ollama/models
|
||||
rpi_dns:
|
||||
host: rpi4
|
||||
pihole_dns_port: 53
|
||||
|
|
|
|||
54
jeannie
54
jeannie
|
|
@ -58,6 +58,8 @@ mapping = {
|
|||
"services.gitea.root_url": "LAB_GITEA_ROOT_URL",
|
||||
"services.gitea.ssh_remote": "LAB_GITOPS_REPO_URL",
|
||||
"services.local_registry.endpoint": "LAB_REGISTRY_ENDPOINT",
|
||||
"services.ollama.bind_address": "LAB_OLLAMA_BIND_ADDRESS",
|
||||
"services.ollama.models_dir": "LAB_OLLAMA_MODELS_DIR",
|
||||
"services.rpi_dns.pihole_web_port": "PIHOLE_WEB_PORT",
|
||||
"services.rpi_dns.uptime_kuma_port": "UPTIME_KUMA_PORT",
|
||||
"ai_gateway.provider": "LAB_AI_GATEWAY_PROVIDER",
|
||||
|
|
@ -3389,9 +3391,10 @@ website_translation_model() {
|
|||
}
|
||||
|
||||
website_ollama_listen() {
|
||||
local bind_address="${WEBSITE_OLLAMA_BIND_ADDRESS:-0.0.0.0:11434}"
|
||||
local bind_address="${WEBSITE_OLLAMA_BIND_ADDRESS:-${LAB_OLLAMA_BIND_ADDRESS:-0.0.0.0:11434}}"
|
||||
local models_dir="${LAB_OLLAMA_MODELS_DIR:-/data/ollama/models}"
|
||||
local dropin_dir="/etc/systemd/system/ollama.service.d"
|
||||
local dropin_file="${dropin_dir}/homelab-listen.conf"
|
||||
local dropin_file="${dropin_dir}/homelab.conf"
|
||||
|
||||
require_debian_server "website-ollama-listen"
|
||||
|
||||
|
|
@ -3402,7 +3405,11 @@ website_ollama_listen() {
|
|||
|
||||
echo "Configuring ollama.service to listen on ${bind_address}..."
|
||||
sudo mkdir -p "${dropin_dir}"
|
||||
printf '[Service]\nEnvironment="OLLAMA_HOST=%s"\n' "${bind_address}" |
|
||||
sudo mkdir -p "${models_dir}"
|
||||
if id ollama >/dev/null 2>&1; then
|
||||
sudo chown ollama:ollama "${models_dir}"
|
||||
fi
|
||||
printf '[Service]\nEnvironment="OLLAMA_HOST=%s"\nEnvironment="OLLAMA_MODELS=%s"\n' "${bind_address}" "${models_dir}" |
|
||||
sudo tee "${dropin_file}" >/dev/null
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart ollama.service
|
||||
|
|
@ -3413,6 +3420,42 @@ website_ollama_listen() {
|
|||
echo "Ollama API is reachable on the Debian host."
|
||||
}
|
||||
|
||||
ollama_setup() {
|
||||
local bind_address="${LAB_OLLAMA_BIND_ADDRESS:-0.0.0.0:11434}"
|
||||
local models_dir="${LAB_OLLAMA_MODELS_DIR:-/data/ollama/models}"
|
||||
local model="${LAB_AI_GATEWAY_MODEL:-qwen2.5:0.5b}"
|
||||
local installer_url="${LAB_OLLAMA_INSTALL_URL:-https://ollama.com/install.sh}"
|
||||
local tmp_installer
|
||||
|
||||
require_debian_server "ollama-setup"
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "curl is required to install Ollama." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v ollama >/dev/null 2>&1; then
|
||||
echo "Installing Ollama from ${installer_url}..."
|
||||
tmp_installer="$(mktemp)"
|
||||
curl -fsSL "${installer_url}" -o "${tmp_installer}"
|
||||
sudo sh "${tmp_installer}"
|
||||
rm -f "${tmp_installer}"
|
||||
else
|
||||
echo "Ollama is already installed: $(command -v ollama)"
|
||||
fi
|
||||
|
||||
website_ollama_listen
|
||||
|
||||
echo "Ensuring Ollama model ${model} is available..."
|
||||
if ollama list | awk -v model="${model}" 'NR > 1 && ($1 == model || $1 == model ":latest") { found = 1 } END { exit found ? 0 : 1 }'; then
|
||||
echo "Ollama model ${model} is already present."
|
||||
else
|
||||
OLLAMA_HOST=http://127.0.0.1:11434 ollama pull "${model}"
|
||||
fi
|
||||
|
||||
echo "Ollama homelab setup is ready."
|
||||
}
|
||||
|
||||
apps() {
|
||||
local buildx_builder_ready=false
|
||||
local demos_image_built=false
|
||||
|
|
@ -4728,6 +4771,9 @@ case "${1:-}" in
|
|||
website-ollama-listen)
|
||||
website_ollama_listen
|
||||
;;
|
||||
ollama-setup)
|
||||
ollama_setup
|
||||
;;
|
||||
deploy-gitea)
|
||||
deploy_gitea
|
||||
;;
|
||||
|
|
@ -4789,7 +4835,7 @@ case "${1:-}" in
|
|||
nuke
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {up|rebuild-cluster|stop-cluster|start-cluster|status|apps|website-translation-model|website-ollama-listen|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-gitea-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|openwrt|nuke}"
|
||||
echo "Usage: $0 {up|rebuild-cluster|stop-cluster|start-cluster|status|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-gitea-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|openwrt|nuke}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
|
|||
Loading…
Reference in New Issue