--- - name: Deploy Ollama + Open WebUI hosts: your_gpu_servers become: yes vars: ollama_port: 11434 open_webui_port: "{{ lookup('env', 'OPEN_WEBUI_PORT') | default('3000') }}" ollama_volume_name: ollama_ollama open_webui_volume_name: ollama_open_webui webui_secret_key: "vk4HCy3FnlF0fqRT8MClJSGVmEdsP2tK" # ← move to ansible-vault in production! tasks: - name: Create named volumes (optional but cleaner than host paths) community.docker.docker_volume: name: "{{ item }}" state: present loop: - "{{ ollama_volume_name }}" - "{{ open_webui_volume_name }}" - name: Deploy Ollama container community.docker.docker_container: name: ollama image: ollama/ollama:latest state: started restart_policy: unless-stopped pull: true tty: true published_ports: - "{{ ollama_port }}:11434" volumes: - "{{ ollama_volume_name }}:/root/.ollama" device_requests: - driver: nvidia count: -1 # -1 = all GPUs (or use device_ids: ['0', '1'] for specific) capabilities: - - gpu # nested list as per docs comparisons: image: strict env: strict volumes: strict # container_default_behavior: no_defaults # optional, modern default register: ollama_deploy - name: Deploy Open WebUI container community.docker.docker_container: name: open-webui image: ghcr.io/open-webui/open-webui:main state: started restart_policy: unless-stopped pull: true published_ports: - "{{ open_webui_port }}:8080" volumes: - "{{ open_webui_volume_name }}:/app/backend/data" env: OLLAMA_BASE_URL: "http://ollama:11434" # container → container via name WEBUI_SECRET_KEY: "{{ webui_secret_key }}" extra_hosts: host.docker.internal: host-gateway # networks: # - name: bridge # default anyway 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 - name: Wait for Ollama to be ready ansible.builtin.uri: url: "http://localhost:{{ ollama_port }}/api/tags" method: GET status_code: 200 return_content: no register: ollama_ready until: ollama_ready.status == 200 retries: 30 delay: 5 when: ollama_deploy.changed - name: Debug deployment status ansible.builtin.debug: msg: - "Ollama container: {{ ollama_deploy.container.State.Status | default('unknown') }}" - "Open WebUI listening on port {{ open_webui_port }}"