diff --git a/README.md b/README.md index b27c6b2a9..1e45c8c86 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ If you have a spare domain name you can configure applications to be accessible * [openHAB](https://www.openhab.org/) - A vendor and technology agnostic open source automation software for your home * [openLDAP](https://www.openldap.org/) - An open source implementation of the Lightweight Directory Access Protocol * [Open-resume](https://github.com/xitanggg/open-resume) - A powerful open-source resume builder and resume parser +* [Open-WebUI](https://github.com/open-webui/open-webui) - User-friendly WebUI for LLMs (Formerly Ollama WebUI) * [Organizr](https://organizr.app/) - ORGANIZR aims to be your one stop shop for your Servers Frontend. * [Outline](https://github.com/outline/outline) - The fastest knowledge base for growing teams. * [Overleaf](https://github.com/overleaf/overleaf) - A web-based collaborative LaTeX editor diff --git a/nas.yml b/nas.yml index 43618a9d0..3f132b0c9 100644 --- a/nas.yml +++ b/nas.yml @@ -629,6 +629,10 @@ tags: - openresume + - role: openwebui + tags: + - openwebui + - role: organizr tags: - organizr diff --git a/roles/openwebui/defaults/main.yml b/roles/openwebui/defaults/main.yml new file mode 100644 index 000000000..8f1dc1ccd --- /dev/null +++ b/roles/openwebui/defaults/main.yml @@ -0,0 +1,115 @@ +--- +openwebui_enabled: false +openwebui_available_externally: false + +# directories +openwebui_data_directory: "{{ docker_home }}/openwebui" + +# network +openwebui_ollama_port: "11434" +openwebui_ui_port: "8155" +openwebui_hostname: "openwebui" +openwebui_network_name: "openwebui" + +# specs +openwebui_ollama_memory: 1g +openwebui_ui_memory: 1g + +# docker +openwebui_ollama_container_name: openwebui-ollama +openwebui_ollama_image_name: "ollama/ollama" +openwebui_ollama_image_version: latest # rocm +openwebui_ui_container_name: openwebui-ui +openwebui_ui_image_name: "ghcr.io/open-webui/open-webui" +openwebui_ui_image_version: main +openwebui_user_id: "1000" +openwebui_group_id: "1000" + +# openwebui +openwebui_ollama_base_url: "http://{{ openwebui_ollama_container_name }}:11434" +openwebui_openai_api_base_url: "" +openwebui_openai_api_key: "" +openwebui_scarf_no_analytics: "true" +openwebui_do_not_track: "true" +openwebui_anonymized_telemetry: "false" +openwebui_webui_secret_key: "super_secret" +openwebui_webui_auth: "true" +openwebui_webui_name: "Open WebUI" +openwebui_webui_url: "https://{{ openwebui_hostname }}.{{ ansible_nas_domain }}" +openwebui_env_var: "prod" +openwebui_enable_signup: "true" +openwebui_enable_rag_web_loader_ssl_verification: "true" +openwebui_default_models: "" +openwebui_default_user_role: "pending" # pensing, user, admin +openwebui_user_permissions_chat_deletion: "true" +openwebui_enable_model_filter: "false" +openwebui_model_filter_list: "" # Example: llama3:instruct;gemma:instruct +openwebui_webhook_url: "{{ openwebui_webui_url }}" +openwebui_enable_admin_export: "true" +openwebui_enable_community_sharing: "true" +openwebui_webui_build_hash: "dev-build" +openwebui_webui_banners: + - id: "1" + type: "success" + title: "Welcome to Open WebUI!" + content: "Thanks for installing Open WebUI!" + dismissible: false + timestamp: 1000 + - id: "2" + type: "warning" + title: "Watch out for models" + content: "Please make sure to import models!" + dismissible: false + timestamp: 1000 +openwebui_searxng_query_url: http://searxng.local/search?q= +openwebui_enable_image_generation: "false" +openwebui_image_generation_engine: "openai" # Options: openai, comfyui, automatic1111 +openwebui_automatic1111_base_url: "" +openwebui_comfyui_base_url: "" +openwebui_image_size: "512x512" +openwebui_image_steps: "50" +openwebui_image_generation_model: "" +openwebui_ollama_devices: +# - /dev/kfd:/dev/kfd +# - /dev/dri:/dev/dri + +openwebui_env: + # Ollama URL for the backend to connect + # The path '/ollama' will be redirected to the specified backend URL + OLLAMA_BASE_URL: "{{ openwebui_ollama_base_url }}" + OPENAI_API_BASE_URL: "{{ openwebui_openai_api_base_url }}" + OPENAI_API_KEY: "{{ openwebui_openai_api_key }}" + + # AUTOMATIC1111_BASE_URL="http://localhost:7860" + + # DO NOT TRACK + SCARF_NO_ANALYTICS: "{{ openwebui_scarf_no_analytics }}" + DO_NOT_TRACK: "{{ openwebui_do_not_track }}" + ANONYMIZED_TELEMETRY: "{{ openwebui_anonymized_telemetry }}" + WEBUI_SECRET_KEY: "{{ openwebui_webui_secret_key }}" + WEBUI_AUTH: "{{ openwebui_webui_auth }}" + WEBUI_NAME: "{{ openwebui_webui_name }}" + WEBUI_URL: "{{ openwebui_webui_url }}" + ENV: "{{ openwebui_env_var }}" + ENABLE_SIGNUP: "{{ openwebui_enable_signup }}" + ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION: "{{ openwebui_enable_rag_web_loader_ssl_verification }}" + DEFAULT_MODELS: "{{ openwebui_default_models }}" + DEFAULT_USER_ROLE: "{{ openwebui_default_user_role }}" + USER_PERMISSIONS_CHAT_DELETION: "{{ openwebui_user_permissions_chat_deletion }}" + ENABLE_MODEL_FILTER: "{{ openwebui_enable_model_filter }}" + MODEL_FILTER_LIST: "{{ openwebui_model_filter_list }}" + WEBHOOK_URL: "{{ openwebui_webhook_url }}" + ENABLE_ADMIN_EXPORT: "{{ openwebui_enable_admin_export }}" + ENABLE_COMMUNITY_SHARING: "{{ openwebui_enable_community_sharing }}" + WEBUI_BUILD_HASH: "{{ openwebui_webui_build_hash }}" + WEBUI_BANNERS: "{{ openwebui_webui_banners | to_json }}" + SEARXNG_QUERY_URL: "{{ openwebui_searxng_query_url }}" + ENABLE_IMAGE_GENERATION: "{{ openwebui_enable_image_generation }}" + IMAGE_GENERATION_ENGINE: "{{ openwebui_image_generation_engine }}" + AUTOMATIC1111_BASE_URL: "{{ openwebui_automatic1111_base_url }}" + COMFYUI_BASE_URL: "{{ openwebui_comfyui_base_url }}" + IMAGES_OPENAI_API_KEY: "{{ openwebui_openai_api_key }}" + IMAGES_OPENAI_API_BASE_URL: "{{ openwebui_openai_api_base_url }}" + IMAGE_SIZE: "{{ openwebui_image_size }}" + IMAGE_STEPS: "{{ openwebui_image_steps }}" + IMAGE_GENERATION_MODEL: "{{ openwebui_image_generation_model }}" diff --git a/roles/openwebui/docs/openwebui.md b/roles/openwebui/docs/openwebui.md new file mode 100644 index 000000000..1971951f2 --- /dev/null +++ b/roles/openwebui/docs/openwebui.md @@ -0,0 +1,11 @@ +# Open-WebUI + +Homepage: [https://github.com/open-webui/open-webui](https://github.com/open-webui/open-webui) + +User-friendly WebUI for LLMs (Formerly Ollama WebUI) + +## Usage + +Set `openwebui_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Open-WebUI web interface can be found at [http://ansible_nas_host_or_ip:8155](http://ansible_nas_host_or_ip:8155). diff --git a/roles/openwebui/molecule/default/molecule.yml b/roles/openwebui/molecule/default/molecule.yml new file mode 100644 index 000000000..dc9e538b8 --- /dev/null +++ b/roles/openwebui/molecule/default/molecule.yml @@ -0,0 +1,6 @@ +--- +provisioner: + inventory: + group_vars: + all: + openwebui_enabled: true diff --git a/roles/openwebui/molecule/default/side_effect.yml b/roles/openwebui/molecule/default/side_effect.yml new file mode 100644 index 000000000..1b0621c7f --- /dev/null +++ b/roles/openwebui/molecule/default/side_effect.yml @@ -0,0 +1,10 @@ +--- +- name: Stop + hosts: all + become: true + tasks: + - name: "Include {{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }} role" + ansible.builtin.include_role: + name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + vars: + openwebui_enabled: false diff --git a/roles/openwebui/molecule/default/verify.yml b/roles/openwebui/molecule/default/verify.yml new file mode 100644 index 000000000..7a5c363cc --- /dev/null +++ b/roles/openwebui/molecule/default/verify.yml @@ -0,0 +1,26 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Get openwebui ollama container state + community.docker.docker_container: + name: "{{ openwebui_ollama_container_name }}" + register: result_ollama + + - name: Get openwebui ui container state + community.docker.docker_container: + name: "{{ openwebui_ui_container_name }}" + register: result_ui + + - name: Check if openwebui containers are running + ansible.builtin.assert: + that: + - result_ollama.container['State']['Status'] == "running" + - result_ollama.container['State']['Restarting'] == false + - result_ui.container['State']['Status'] == "running" + - result_ui.container['State']['Restarting'] == false diff --git a/roles/openwebui/molecule/default/verify_stopped.yml b/roles/openwebui/molecule/default/verify_stopped.yml new file mode 100644 index 000000000..46538f24f --- /dev/null +++ b/roles/openwebui/molecule/default/verify_stopped.yml @@ -0,0 +1,26 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Try and stop and remove openwebui ollama + community.docker.docker_container: + name: "{{ openwebui_ollama_container_name }}" + state: absent + register: result_ollama + + - name: Try and stop and remove openwebui ui + community.docker.docker_container: + name: "{{ openwebui_ui_container_name }}" + state: absent + register: result_ui + + - name: Check if openwebui is stopped + ansible.builtin.assert: + that: + - not result_ollama.changed + - not result_ui.changed diff --git a/roles/openwebui/requirements.yml b/roles/openwebui/requirements.yml new file mode 120000 index 000000000..9a736435a --- /dev/null +++ b/roles/openwebui/requirements.yml @@ -0,0 +1 @@ +../../requirements.yml \ No newline at end of file diff --git a/roles/openwebui/tasks/main.yml b/roles/openwebui/tasks/main.yml new file mode 100644 index 000000000..47ed2072f --- /dev/null +++ b/roles/openwebui/tasks/main.yml @@ -0,0 +1,70 @@ +--- +- name: Start Open-WebUI + block: + - name: Create Open-WebUI Directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + with_items: + - "{{ openwebui_data_directory }}" + + - name: Create Open-WebUI network + community.docker.docker_network: + name: "{{ openwebui_network_name }}" + + - name: Create Open-WebUI Ollama Docker Container + community.docker.docker_container: + name: "{{ openwebui_ollama_container_name }}" + image: "{{ openwebui_ollama_image_name }}:{{ openwebui_ollama_image_version }}" + pull: true + ports: + - "{{ openwebui_ollama_port }}:11434" + devices: "{{ openwebui_ollama_devices }}" + volumes: + - "{{ openwebui_data_directory }}/ollama:/root/.ollama:rw" + networks: + - name: "{{ openwebui_network_name }}" + network_mode: "{{ openwebui_network_name }}" + container_default_behavior: no_defaults + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ openwebui_ollama_memory }}" + + - name: Create Open-WebUI UI Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ openwebui_ui_container_name }}" + image: "{{ openwebui_ui_image_name }}:{{ openwebui_ui_image_version }}" + pull: true + networks: + - name: "{{ openwebui_network_name }}" + network_mode: "{{ openwebui_network_name }}" + ports: + - "{{ openwebui_ui_port }}:8080" + volumes: + - "{{ openwebui_data_directory }}/open-webui:/app/backend/data:rw" + env: "{{ openwebui_env }}" + restart_policy: unless-stopped + memory: "{{ openwebui_ui_memory }}" + labels: + traefik.enable: "{{ openwebui_available_externally | string }}" + traefik.http.routers.openwebui.rule: "Host(`{{ openwebui_hostname }}.{{ ansible_nas_domain }}`)" + traefik.http.routers.openwebui.tls.certresolver: "letsencrypt" + traefik.http.routers.openwebui.tls.domains[0].main: "{{ ansible_nas_domain }}" + traefik.http.routers.openwebui.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.services.openwebui.loadbalancer.server.port: "8080" + when: openwebui_enabled is true + +- name: Stop Open-WebUI + block: + - name: Stop Open-WebUI Ollama + community.docker.docker_container: + name: "{{ openwebui_ollama_container_name }}" + state: absent + + - name: Stop Open-WebUI + community.docker.docker_container: + name: "{{ openwebui_ui_container_name }}" + state: absent + when: openwebui_enabled is false diff --git a/website/docs/applications/other/openwebui.md b/website/docs/applications/other/openwebui.md new file mode 100644 index 000000000..77784238e --- /dev/null +++ b/website/docs/applications/other/openwebui.md @@ -0,0 +1,14 @@ +--- +title: "Open-WebUI" +description: "User-friendly WebUI for LLMs (Formerly Ollama WebUI)" +--- + +Homepage: [https://github.com/open-webui/open-webui](https://github.com/open-webui/open-webui) + +User-friendly WebUI for LLMs (Formerly Ollama WebUI) + +## Usage + +Set `openwebui_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Open-WebUI web interface can be found at [http://ansible_nas_host_or_ip:8155](http://ansible_nas_host_or_ip:8155).