From 3dc2fbd47c3364aa690cc817eef0ebf514c7cf41 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Mon, 22 Sep 2025 16:27:51 +0200 Subject: [PATCH] refactor(objstore): extract MinIO into dedicated role 'web-app-minio' and adjust AI role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Rename ports: web-app-ai_minio_* → web-app-minio_* in group_vars • Remove MinIO from web-app-ai (service, volumes, ENV) • Add new role web-app-minio (config, tasks, compose, env, vars) incl. front-proxy matrix • AI role: front-proxy loop via matrix; unify domain/port vars (OPENWEBUI/Flowise *_PORT_PUBLIC/_PORT_INTERNAL, *_DOMAIN) • Update compose templates accordingly Ref: https://chatgpt.com/share/68d15cb8-cf18-800f-b853-78962f751f81 --- group_vars/all/10_ports.yml | 6 +-- roles/web-app-ai/config/main.yml | 8 ---- roles/web-app-ai/tasks/main.yml | 24 +++++++++++ .../templates/docker-compose.yml.j2 | 18 +-------- roles/web-app-ai/templates/env.j2 | 6 +-- roles/web-app-ai/vars/main.yml | 36 ++++------------- roles/web-app-minio/config/main.yml | 40 +++++++++++++++++++ roles/web-app-minio/tasks/main.yml | 16 ++++++++ .../templates/docker-compose.yml.j2 | 17 ++++++++ roles/web-app-minio/templates/env.J2 | 3 ++ roles/web-app-minio/vars/main.yml | 31 ++++++++++++++ 11 files changed, 145 insertions(+), 60 deletions(-) create mode 100644 roles/web-app-ai/tasks/main.yml create mode 100644 roles/web-app-minio/config/main.yml create mode 100644 roles/web-app-minio/tasks/main.yml create mode 100644 roles/web-app-minio/templates/docker-compose.yml.j2 create mode 100644 roles/web-app-minio/templates/env.J2 create mode 100644 roles/web-app-minio/vars/main.yml diff --git a/group_vars/all/10_ports.yml b/group_vars/all/10_ports.yml index abf3cb50..82c94e25 100644 --- a/group_vars/all/10_ports.yml +++ b/group_vars/all/10_ports.yml @@ -75,11 +75,11 @@ ports: web-app-bluesky_view: 8051 web-app-magento: 8052 web-app-bridgy-fed: 8053 - web-app-xwiki: 8054 + web-app-xwiki: 8054 web-app-ai_openwebui: 8055 web-app-ai_flowise: 8056 - web-app-ai_minio_api: 8057 - web-app-ai_minio_console: 8058 + web-app-minio_api: 8057 + web-app-minio_console: 8058 web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port public: # The following ports should be changed to 22 on the subdomain via stream mapping diff --git a/roles/web-app-ai/config/main.yml b/roles/web-app-ai/config/main.yml index 3d8bbf32..e389ef13 100644 --- a/roles/web-app-ai/config/main.yml +++ b/roles/web-app-ai/config/main.yml @@ -10,7 +10,6 @@ server: canonical: openwebui: "chat.ai.{{ PRIMARY_DOMAIN }}" flowise: "flowise.ai.{{ PRIMARY_DOMAIN }}" - minio: "minio.ai.{{ PRIMARY_DOMAIN }}" aliases: [] csp: flags: [] @@ -58,12 +57,6 @@ docker: image: flowiseai/flowise:latest version: latest name: flowise - minio: - backup: - no_stop_required: true - image: quay.io/minio/minio:latest - version: latest - name: minio redis: enabled: false database: @@ -73,6 +66,5 @@ docker: ollama: ai_ollama_models qdrant: ai_qdrant_data flowise: ai_flowise_data - minio: ai_minio_data credentials: {} diff --git a/roles/web-app-ai/tasks/main.yml b/roles/web-app-ai/tasks/main.yml new file mode 100644 index 00000000..48f3040e --- /dev/null +++ b/roles/web-app-ai/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: "load docker and db for {{ application_id }}" + include_role: + name: sys-stk-back-stateless + vars: + docker_compose_flush_handlers: false + +- name: "create {{ AI_LITELLM_CONFIG_PATH_HOST }}" + template: src: "litellm.config.yaml.j2" + dest: "{{ AI_LITELLM_CONFIG_PATH_HOST }}" + notify: docker compose up + +- name: "flush handlers of docker compose" + meta: flush_handlers + +- name: "Include role sys-stk-front-proxy for each UI domain" + include_role: + name: sys-stk-front-proxy + vars: + domain: "{{ item.domain }}" + http_port: "{{ item.http_port }}" + loop: "{{ AI_FRONT_PROXY_MATRIX }}" + loop_control: + label: "{{ item.domain }} -> {{ item.http_port }}" diff --git a/roles/web-app-ai/templates/docker-compose.yml.j2 b/roles/web-app-ai/templates/docker-compose.yml.j2 index f557515f..846a8688 100644 --- a/roles/web-app-ai/templates/docker-compose.yml.j2 +++ b/roles/web-app-ai/templates/docker-compose.yml.j2 @@ -16,7 +16,7 @@ depends_on: - ollama ports: - - "127.0.0.1:{{ AI_OPENWEBUI_PORT }}:8080" + - "127.0.0.1:{{ AI_OPENWEBUI_PORT_PUBLIC }}:8080" volumes: - openwebui_data:/app/backend/data {% include 'roles/docker-container/templates/networks.yml.j2' %} @@ -56,23 +56,11 @@ - qdrant - litellm ports: - - "127.0.0.1:{{ AI_FLOWISE_PUBLIC_PORT }}:{{ AI_FLOWISE_INTERNAL_PORT }}" + - "127.0.0.1:{{ AI_FLOWISE_PORT_PUBLIC }}:{{ AI_FLOWISE_PORT_INTERNAL }}" volumes: - flowise_data:/root/.flowise {% include 'roles/docker-container/templates/networks.yml.j2' %} - minio: -{% include 'roles/docker-container/templates/base.yml.j2' %} - image: {{ AI_MINIO_IMAGE }}:{{ AI_MINIO_VERSION }} - container_name: {{ AI_MINIO_CONTAINER }} - ports: - - "127.0.0.1:{{ AI_MINIO_API_PUBLIC_PORT }}:9000" - - "127.0.0.1:{{ AI_MINIO_CONSOLE_PUBLIC_PORT }}:{{ AI_MINIO_CONSOLE_INTERNAL_PORT }}" - command: server /data --console-address ":{{ AI_MINIO_CONSOLE_INTERNAL_PORT }}" - volumes: - - minio_data:/data -{% include 'roles/docker-container/templates/networks.yml.j2' %} - {% include 'roles/docker-compose/templates/networks.yml.j2' %} {% include 'roles/docker-compose/templates/volumes.yml.j2' %} @@ -84,5 +72,3 @@ name: {{ AI_QDRANT_VOLUME }} flowise_data: name: {{ AI_FLOWISE_VOLUME }} - minio_data: - name: {{ AI_MINIO_VOLUME }} diff --git a/roles/web-app-ai/templates/env.j2 b/roles/web-app-ai/templates/env.j2 index 161a6d03..0e811de8 100644 --- a/roles/web-app-ai/templates/env.j2 +++ b/roles/web-app-ai/templates/env.j2 @@ -9,7 +9,7 @@ LITELLM_MASTER_KEY=dummy-key LITELLM_CONFIG=/etc/litellm/config.yaml # Flowise -PORT={{ AI_FLOWISE_INTERNAL_PORT }} +PORT={{ AI_FLOWISE_PORT_INTERNAL }} FLOWISE_USERNAME=admin FLOWISE_PASSWORD=admin DATABASE_PATH=/root/.flowise @@ -19,7 +19,3 @@ FLOWISE_FILE_STORAGE_PATH=/root/.flowise/storage QDRANT_URL={{ AI_QDRANT_INTERNAL_URL }} OPENAI_API_BASE={{ AI_LITELLM_INTERNAL_URL }}/v1 OPENAI_API_KEY=dummy-key - -# MINIO -MINIO_ROOT_USER=admin -MINIO_ROOT_PASSWORD=adminadmin \ No newline at end of file diff --git a/roles/web-app-ai/vars/main.yml b/roles/web-app-ai/vars/main.yml index 9b573ab5..c47d9c91 100644 --- a/roles/web-app-ai/vars/main.yml +++ b/roles/web-app-ai/vars/main.yml @@ -1,6 +1,6 @@ # General -application_id: "web-app-ai" +application_id: "web-app-ai" # Docker docker_pull_git_repository: false @@ -8,18 +8,17 @@ docker_compose_file_creation_enabled: true # Open WebUI # https://openwebui.com/ -AI_OPENWEBUI_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" AI_OPENWEBUI_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.openwebui.version') }}" AI_OPENWEBUI_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.openwebui.image') }}" AI_OPENWEBUI_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.openwebui.name') }}" AI_OPENWEBUI_OFFLINE_MODE: "{{ applications | get_app_conf(application_id, 'docker.services.openwebui.offline_mode') }}" AI_OPENWEBUI_HF_HUB_OFFLINE: "{{ applications | get_app_conf(application_id, 'docker.services.openwebui.hf_hub_offline') }}" AI_OPENWEBUI_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.openwebui') }}" -AI_OPENWEBUI_PORT: "{{ ports.localhost.http[application_id ~ '_openwebui'] }}" +AI_OPENWEBUI_PORT_PUBLIC: "{{ ports.localhost.http[application_id ~ '_openwebui'] }}" +AI_OPENWEBUI_DOMAIN: "{{ applications | get_app_conf(application_id, 'server.domains.canonical.openwebui') }}" # Ollama # https://ollama.com/ -AI_OLLAMA_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" AI_OLLAMA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.ollama.version') }}" AI_OLLAMA_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.ollama.image') }}" AI_OLLAMA_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.ollama.name') }}" @@ -29,7 +28,6 @@ AI_OLLAMA_BASE_URL: "http://ollama:{{ AI_OLLAMA_PORT }}" # LiteLLM # https://www.litellm.ai/ -AI_LITELLM_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" AI_LITELLM_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.litellm.version') }}" AI_LITELLM_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.litellm.image') }}" AI_LITELLM_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.litellm.name') }}" @@ -41,7 +39,6 @@ AI_LITELLM_CONFIG_PATH_DOCKER: "/etc/litellm/config.yaml" # Qdrant # https://qdrant.tech/ -AI_QDRANT_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" AI_QDRANT_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.qdrant.version') }}" AI_QDRANT_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.qdrant.image') }}" AI_QDRANT_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.qdrant.name') }}" @@ -52,35 +49,18 @@ AI_QDRANT_INTERNAL_URL: "http://qdrant:{{ AI_QDRANT_HTTP_PORT }}" # Flowise # https://flowiseai.com/ -AI_FLOWISE_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" AI_FLOWISE_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.flowise.version') }}" AI_FLOWISE_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.flowise.image') }}" AI_FLOWISE_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.flowise.name') }}" AI_FLOWISE_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.flowise') }}" -AI_FLOWISE_PUBLIC_PORT: "{{ ports.localhost.http[application_id ~ '_flowise'] }}" -AI_FLOWISE_INTERNAL_PORT: 3000 - -# MINIO -# https://www.min.io/ -AI_MINIO_URL: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" -AI_MINIO_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.minio.version') }}" -AI_MINIO_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.minio.image') }}" -AI_MINIO_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.minio.name') }}" -AI_MINIO_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.minio') }}" -AI_MINIO_API_PUBLIC_PORT: "{{ ports.localhost.http[application_id ~ '_minio_api'] }}" -AI_MINIO_CONSOLE_INTERNAL_PORT: "9001" -AI_MINIO_CONSOLE_PUBLIC_PORT: "{{ ports.localhost.http[application_id ~ '_minio_console'] }}" - +AI_FLOWISE_PORT_PUBLIC: "{{ ports.localhost.http[application_id ~ '_flowise'] }}" +AI_FLOWISE_PORT_INTERNAL: 3000 +AI_FLOWISE_DOMAIN: "{{ applications | get_app_conf(application_id, 'server.domains.canonical.flowise') }}" AI_FRONT_PROXY_MATRIX: >- {{ [ - { 'domain': server.domains.canonical.openwebui, 'http_port': AI_OPENWEBUI_PORT }, - { 'domain': server.domains.canonical.flowise, 'http_port': AI_FLOWISE_PUBLIC_PORT }, - { 'domain': server.domains.canonical.minio, 'http_port': AI_MINIO_CONSOLE_PUBLIC_PORT } + { 'domain': AI_OPENWEBUI_DOMAIN, 'http_port': AI_OPENWEBUI_PORT_PUBLIC }, + { 'domain': AI_FLOWISE_DOMAIN, 'http_port': AI_FLOWISE_PORT_PUBLIC } ] - + ( - [ { 'domain': server.domains.canonical.minio_api, 'http_port': AI_MINIO_API_PUBLIC_PORT } ] - if (server.domains.canonical.minio_api is defined) else [] - ) }} \ No newline at end of file diff --git a/roles/web-app-minio/config/main.yml b/roles/web-app-minio/config/main.yml new file mode 100644 index 00000000..9b266dd9 --- /dev/null +++ b/roles/web-app-minio/config/main.yml @@ -0,0 +1,40 @@ +features: + matomo: true + css: true + desktop: true + central_database: true + logout: true + javascript: false +server: + domains: + canonical: + console: "console.s3.{{ PRIMARY_DOMAIN }}" + api: "api.s3.{{ PRIMARY_DOMAIN }}" + aliases: [] + csp: + flags: [] + #script-src-elem: + # unsafe-inline: true + #script-src: + # unsafe-inline: true + # unsafe-eval: true + #style-src: + # unsafe-inline: true + whitelist: + font-src: [] + connect-src: [] +docker: + services: + minio: + backup: + no_stop_required: true + image: quay.io/minio/minio:latest + version: latest + name: minio + redis: + enabled: false + database: + enabled: false + volumes: + data: minio_data +credentials: {} diff --git a/roles/web-app-minio/tasks/main.yml b/roles/web-app-minio/tasks/main.yml new file mode 100644 index 00000000..f95b6361 --- /dev/null +++ b/roles/web-app-minio/tasks/main.yml @@ -0,0 +1,16 @@ +--- +- name: "load docker and db for {{ application_id }}" + include_role: + name: sys-stk-back-stateless + vars: + docker_compose_flush_handlers: true + +- name: "Include role sys-stk-front-proxy for each UI domain" + include_role: + name: sys-stk-front-proxy + vars: + domain: "{{ item.domain }}" + http_port: "{{ item.http_port }}" + loop: "{{ MINIO_FRONT_PROXY_MATRIX }}" + loop_control: + label: "{{ item.domain }} -> {{ item.http_port }}" diff --git a/roles/web-app-minio/templates/docker-compose.yml.j2 b/roles/web-app-minio/templates/docker-compose.yml.j2 new file mode 100644 index 00000000..4e2edcd8 --- /dev/null +++ b/roles/web-app-minio/templates/docker-compose.yml.j2 @@ -0,0 +1,17 @@ +{% include 'roles/docker-compose/templates/base.yml.j2' %} + + minio: +{% include 'roles/docker-container/templates/base.yml.j2' %} + image: {{ MINIO_IMAGE }}:{{ MINIO_VERSION }} + container_name: {{ MINIO_CONTAINER }} + ports: + - "127.0.0.1:{{ MINIO_API_PORT_PUBLIC }}:{{ MINIO_API_PORT_INTERNAL }}" + - "127.0.0.1:{{ MINIO_CONSOLE_PORT_PUBLIC }}:{{ MINIO_CONSOLE_PORT_INTERNAL }}" + command: server /data --console-address ":{{ MINIO_CONSOLE_PORT_INTERNAL }}" + volumes: + - data:/data +{% include 'roles/docker-container/templates/networks.yml.j2' %} + +{% include 'roles/docker-compose/templates/volumes.yml.j2' %} + data: + name: {{ MINIO_VOLUME }} \ No newline at end of file diff --git a/roles/web-app-minio/templates/env.J2 b/roles/web-app-minio/templates/env.J2 new file mode 100644 index 00000000..1c3caaae --- /dev/null +++ b/roles/web-app-minio/templates/env.J2 @@ -0,0 +1,3 @@ +# MINIO +MINIO_ROOT_USER=admin +MINIO_ROOT_PASSWORD=adminadmin \ No newline at end of file diff --git a/roles/web-app-minio/vars/main.yml b/roles/web-app-minio/vars/main.yml new file mode 100644 index 00000000..90466624 --- /dev/null +++ b/roles/web-app-minio/vars/main.yml @@ -0,0 +1,31 @@ +# General +application_id: "web-app-minio" + +# Docker +docker_pull_git_repository: false +docker_compose_file_creation_enabled: true + +# MINIO +# https://www.min.io/ +MINIO_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.minio.version') }}" +MINIO_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.minio.image') }}" +MINIO_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.minio.name') }}" +MINIO_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.minio') }}" + +## Api +MINIO_API_DOMAIN: "{{ applications | get_app_conf(application_id, 'server.domains.canonical.api') }}" +MINIO_API_PORT_INTERNAL: 9000 +MINIO_API_PORT_PUBLIC: "{{ ports.localhost.http[application_id ~ '_api'] }}" + +## Console +MINIO_CONSOLE_DOMAIN: "{{ applications | get_app_conf(application_id, 'server.domains.canonical.console') }}" +MINIO_CONSOLE_PORT_INTERNAL: 9001 +MINIO_CONSOLE_PORT_PUBLIC: "{{ ports.localhost.http[application_id ~ '_console'] }}" + +MINIO_FRONT_PROXY_MATRIX: >- + {{ + [ + { 'domain': MINIO_CONSOLE_DOMAIN:, 'http_port': MINIO_CONSOLE_PORT_PUBLIC }, + { 'domain': MINIO_API_DOMAIN, 'http_port': MINIO_API_PORT_PUBLIC } + ] + }} \ No newline at end of file