--- # ------------------------------------------------------------ # Ansible Playbook – Deploy Ollama + Open‑WebUI with Podman # ------------------------------------------------------------ - 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: # ----------------------------------------------------------------- # 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') }}" # Secret key for the UI – you can also move this to a vault variable webui_secret_key: "vk4HCy3FnlF0fqRT8MClJSGVmEdsP2tK" # ----------------------------------------------------------------- # 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: # ----------------------------------------------------------------- # 1️⃣ Install Podman (and the NVIDIA container toolkit if you need it) # ----------------------------------------------------------------- - name: Install podman (Debian/Ubuntu) ansible.builtin.apt: name: - podman - ca-certificates - curl - gnupg state: present update_cache: true when: ansible_facts.os_family == "Debian" - name: Install podman (RHEL/CentOS/Fedora) ansible.builtin.dnf: 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 state: present - 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 restart_policy: unless-stopped tty: true pull: true # same as `pull_policy: always` ports: - "11434:11434" volumes: - "ollama:/root/.ollama" # GPU access – expose *all* NVIDIA devices (the same as the compose file) devices: - "/dev/nvidiactl:/dev/nvidiactl" - "/dev/nvidia-uvm:/dev/nvidia-uvm" - "/dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools" - "/dev/nvidia0:/dev/nvidia0" - "/dev/nvidia1:/dev/nvidia1" - "/dev/nvidia2:/dev/nvidia2" - "/dev/nvidia3:/dev/nvidia3" # If you only have a single GPU you can keep just /dev/nvidia0, # or use a loop with `count: all` in the compose – here we expose # 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" # ----------------------------------------------------------------- # 4️⃣ Run the Open‑WebUI container (depends on Ollama) # ----------------------------------------------------------------- - 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 image: "{{ open_webui_image }}" state: started restart_policy: unless-stopped ports: - "{{ open_webui_port }}:8080" volumes: - "open-webui:/app/backend/data" env: OLLAMA_BASE_URL: "http://ollama:11434" WEBUI_SECRET_KEY: "{{ webui_secret_key }}" extra_hosts: - "host.docker.internal:host-gateway" depends_on: - ollama # ensures podman waits for ollama to be up # No special GPU handling needed here – it talks to Ollama over the network # ----------------------------------------------------------------- # 5️⃣ (Optional) Deploy the NPM / Nginx‑Proxy‑Manager service # ----------------------------------------------------------------- # Uncomment the block below if you ever need the commented‑out service # from the original compose file. # # - name: Pull NPM image # containers.podman.podman_image: # name: "{{ npm_image }}" # pull: true # # - name: Start NPM container # 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" # ----------------------------------------------------------------- # 6️⃣ Print a short summary for the operator # ----------------------------------------------------------------- - name: Show deployment summary ansible.builtin.debug: msg: | -------------------------------------------------------------- ✅ Ollama → http://{{ ansible_host }}:11434 ✅ Open‑WebUI → http://{{ ansible_host }}:{{ open_webui_port }} -------------------------------------------------------------- # ------------------------------------------------------------ # End of playbook # ------------------------------------------------------------