update
This commit is contained in:
@@ -1,163 +1,88 @@
|
|||||||
---
|
---
|
||||||
# ------------------------------------------------------------
|
- name: Deploy Ollama + Open WebUI
|
||||||
# Ansible Playbook – Deploy Ollama + Open‑WebUI with Podman
|
hosts: your_gpu_servers
|
||||||
# ------------------------------------------------------------
|
become: yes
|
||||||
- name: Deploy Ollama + Open‑WebUI on a remote host using Podman
|
|
||||||
hosts: target # <-- change to your inventory group / host
|
|
||||||
become: true # we need root to manage containers/volumes
|
|
||||||
vars:
|
vars:
|
||||||
# -----------------------------------------------------------------
|
ollama_port: 11434
|
||||||
# Port that the Open‑WebUI UI will listen on on the *host*.
|
|
||||||
# If you set the environment variable OPEN_WEBUI_PORT on the host
|
|
||||||
# before running the play, that value will be used, otherwise 3000.
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
open_webui_port: "{{ lookup('env', 'OPEN_WEBUI_PORT') | default('3000') }}"
|
open_webui_port: "{{ lookup('env', 'OPEN_WEBUI_PORT') | default('3000') }}"
|
||||||
|
ollama_volume_name: ollama_ollama
|
||||||
# Secret key for the UI – you can also move this to a vault variable
|
open_webui_volume_name: ollama_open_webui
|
||||||
webui_secret_key: "vk4HCy3FnlF0fqRT8MClJSGVmEdsP2tK"
|
webui_secret_key: "vk4HCy3FnlF0fqRT8MClJSGVmEdsP2tK" # ← move to ansible-vault in production!
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
# Container images – pinning to tags is recommended for production.
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
ollama_image: "ollama/ollama:latest"
|
|
||||||
open_webui_image: "ghcr.io/open-webui/open-webui:main"
|
|
||||||
# npm_image: "jc21/nginx-proxy-manager:latest" # (commented out)
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
- name: Create named volumes (optional but cleaner than host paths)
|
||||||
# -----------------------------------------------------------------
|
community.docker.docker_volume:
|
||||||
# 1️⃣ Install Podman (and the NVIDIA container toolkit if you need it)
|
name: "{{ item }}"
|
||||||
# -----------------------------------------------------------------
|
|
||||||
- name: Install podman (Debian/Ubuntu)
|
|
||||||
ansible.builtin.apt:
|
|
||||||
name:
|
|
||||||
- podman
|
|
||||||
- ca-certificates
|
|
||||||
- curl
|
|
||||||
- gnupg
|
|
||||||
state: present
|
state: present
|
||||||
update_cache: true
|
loop:
|
||||||
when: ansible_facts.os_family == "Debian"
|
- "{{ ollama_volume_name }}"
|
||||||
|
- "{{ open_webui_volume_name }}"
|
||||||
|
|
||||||
- name: Install podman (RHEL/CentOS/Fedora)
|
- name: Deploy Ollama container
|
||||||
ansible.builtin.dnf:
|
community.docker.docker_container:
|
||||||
name: podman
|
|
||||||
state: present
|
|
||||||
when: ansible_facts.os_family == "RedHat"
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
# 2️⃣ Create the named Podman volumes
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
- name: Create volume for Ollama data
|
|
||||||
containers.podman.podman_volume:
|
|
||||||
name: ollama
|
name: ollama
|
||||||
state: present
|
image: ollama/ollama:latest
|
||||||
|
|
||||||
- name: Create volume for Open‑WebUI data
|
|
||||||
containers.podman.podman_volume:
|
|
||||||
name: open-webui
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
# 3️⃣ Run the Ollama container (GPU‑enabled)
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
- name: Pull Ollama image
|
|
||||||
containers.podman.podman_image:
|
|
||||||
name: "{{ ollama_image }}"
|
|
||||||
pull: true
|
|
||||||
|
|
||||||
- name: Start Ollama container
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: ollama
|
|
||||||
image: "{{ ollma_image }}"
|
|
||||||
state: started
|
state: started
|
||||||
restart_policy: unless-stopped
|
restart_policy: unless-stopped
|
||||||
|
pull: true
|
||||||
tty: true
|
tty: true
|
||||||
pull: true # same as `pull_policy: always`
|
published_ports:
|
||||||
ports:
|
- "{{ ollama_port }}:11434"
|
||||||
- "11434:11434"
|
|
||||||
volumes:
|
volumes:
|
||||||
- "ollama:/root/.ollama"
|
- "{{ ollama_volume_name }}:/root/.ollama"
|
||||||
# GPU access – expose *all* NVIDIA devices (the same as the compose file)
|
device_requests:
|
||||||
devices:
|
- driver: nvidia
|
||||||
- "/dev/nvidiactl:/dev/nvidiactl"
|
count: -1 # -1 = all GPUs (or use device_ids: ['0', '1'] for specific)
|
||||||
- "/dev/nvidia-uvm:/dev/nvidia-uvm"
|
capabilities:
|
||||||
- "/dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools"
|
- - gpu # nested list as per docs
|
||||||
- "/dev/nvidia0:/dev/nvidia0"
|
comparisons:
|
||||||
- "/dev/nvidia1:/dev/nvidia1"
|
image: strict
|
||||||
- "/dev/nvidia2:/dev/nvidia2"
|
env: strict
|
||||||
- "/dev/nvidia3:/dev/nvidia3"
|
volumes: strict
|
||||||
# If you only have a single GPU you can keep just /dev/nvidia0,
|
# container_default_behavior: no_defaults # optional, modern default
|
||||||
# or use a loop with `count: all` in the compose – here we expose
|
register: ollama_deploy
|
||||||
# the typical device nodes. Adjust if your system uses a different
|
|
||||||
# naming scheme.
|
|
||||||
env:
|
|
||||||
# Optional – explicit, matches the commented out env in the compose
|
|
||||||
NVIDIA_VISIBLE_DEVICES: "all"
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
- name: Deploy Open WebUI container
|
||||||
# 4️⃣ Run the Open‑WebUI container (depends on Ollama)
|
community.docker.docker_container:
|
||||||
# -----------------------------------------------------------------
|
|
||||||
- name: Pull Open‑WebUI image
|
|
||||||
containers.podman.podman_image:
|
|
||||||
name: "{{ open_webui_image }}"
|
|
||||||
pull: true
|
|
||||||
|
|
||||||
- name: Start Open‑WebUI container
|
|
||||||
containers.podman.podman_container:
|
|
||||||
name: open-webui
|
name: open-webui
|
||||||
image: "{{ open_webui_image }}"
|
image: ghcr.io/open-webui/open-webui:main
|
||||||
state: started
|
state: started
|
||||||
restart_policy: unless-stopped
|
restart_policy: unless-stopped
|
||||||
ports:
|
pull: true
|
||||||
|
published_ports:
|
||||||
- "{{ open_webui_port }}:8080"
|
- "{{ open_webui_port }}:8080"
|
||||||
volumes:
|
volumes:
|
||||||
- "open-webui:/app/backend/data"
|
- "{{ open_webui_volume_name }}:/app/backend/data"
|
||||||
env:
|
env:
|
||||||
OLLAMA_BASE_URL: "http://ollama:11434"
|
OLLAMA_BASE_URL: "http://ollama:11434" # container → container via name
|
||||||
WEBUI_SECRET_KEY: "{{ webui_secret_key }}"
|
WEBUI_SECRET_KEY: "{{ webui_secret_key }}"
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
- "host.docker.internal:host-gateway"
|
host.docker.internal: host-gateway
|
||||||
depends_on:
|
# networks:
|
||||||
- ollama # ensures podman waits for ollama to be up
|
# - name: bridge # default anyway
|
||||||
# No special GPU handling needed here – it talks to Ollama over the network
|
depends_on: [] # no real depends_on in docker_container → use wait or handler if critical
|
||||||
|
comparisons:
|
||||||
|
image: strict
|
||||||
|
env: strict
|
||||||
|
volumes: strict
|
||||||
|
when: ollama_deploy.changed or not ollama_deploy.container # optional: only if ollama exists/changed
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# Optional: wait for Ollama API to become responsive before starting WebUI
|
||||||
# 5️⃣ (Optional) Deploy the NPM / Nginx‑Proxy‑Manager service
|
- name: Wait for Ollama to be ready
|
||||||
# -----------------------------------------------------------------
|
ansible.builtin.uri:
|
||||||
# Uncomment the block below if you ever need the commented‑out service
|
url: "http://localhost:{{ ollama_port }}/api/tags"
|
||||||
# from the original compose file.
|
method: GET
|
||||||
#
|
status_code: 200
|
||||||
# - name: Pull NPM image
|
return_content: no
|
||||||
# containers.podman.podman_image:
|
register: ollama_ready
|
||||||
# name: "{{ npm_image }}"
|
until: ollama_ready.status == 200
|
||||||
# pull: true
|
retries: 30
|
||||||
#
|
delay: 5
|
||||||
# - name: Start NPM container
|
when: ollama_deploy.changed
|
||||||
# containers.podman.podman_container:
|
|
||||||
# name: npm
|
|
||||||
# image: "{{ npm_image }}"
|
|
||||||
# state: started
|
|
||||||
# restart_policy: unless-stopped
|
|
||||||
# ports:
|
|
||||||
# - "80:80"
|
|
||||||
# - "81:81"
|
|
||||||
# - "443:443"
|
|
||||||
# volumes:
|
|
||||||
# - "./data:/data"
|
|
||||||
# - "./letsencrypt:/etc/letsencrypt"
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
- name: Debug deployment status
|
||||||
# 6️⃣ Print a short summary for the operator
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
- name: Show deployment summary
|
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: |
|
msg:
|
||||||
--------------------------------------------------------------
|
- "Ollama container: {{ ollama_deploy.container.State.Status | default('unknown') }}"
|
||||||
✅ Ollama → http://{{ ansible_host }}:11434
|
- "Open WebUI listening on port {{ open_webui_port }}"
|
||||||
✅ Open‑WebUI → http://{{ ansible_host }}:{{ open_webui_port }}
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
# End of playbook
|
|
||||||
# ------------------------------------------------------------
|
|
||||||
Reference in New Issue
Block a user