refactor(objstore): extract MinIO into dedicated role 'web-app-minio' and adjust AI role

• 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
This commit is contained in:
2025-09-22 16:27:51 +02:00
parent 4b56ab3d18
commit 3dc2fbd47c
11 changed files with 145 additions and 60 deletions

View File

@@ -75,11 +75,11 @@ ports:
web-app-bluesky_view: 8051 web-app-bluesky_view: 8051
web-app-magento: 8052 web-app-magento: 8052
web-app-bridgy-fed: 8053 web-app-bridgy-fed: 8053
web-app-xwiki: 8054 web-app-xwiki: 8054
web-app-ai_openwebui: 8055 web-app-ai_openwebui: 8055
web-app-ai_flowise: 8056 web-app-ai_flowise: 8056
web-app-ai_minio_api: 8057 web-app-minio_api: 8057
web-app-ai_minio_console: 8058 web-app-minio_console: 8058
web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port web-app-bigbluebutton: 48087 # This port is predefined by bbb. @todo Try to change this to a 8XXX port
public: public:
# The following ports should be changed to 22 on the subdomain via stream mapping # The following ports should be changed to 22 on the subdomain via stream mapping

View File

@@ -10,7 +10,6 @@ server:
canonical: canonical:
openwebui: "chat.ai.{{ PRIMARY_DOMAIN }}" openwebui: "chat.ai.{{ PRIMARY_DOMAIN }}"
flowise: "flowise.ai.{{ PRIMARY_DOMAIN }}" flowise: "flowise.ai.{{ PRIMARY_DOMAIN }}"
minio: "minio.ai.{{ PRIMARY_DOMAIN }}"
aliases: [] aliases: []
csp: csp:
flags: [] flags: []
@@ -58,12 +57,6 @@ docker:
image: flowiseai/flowise:latest image: flowiseai/flowise:latest
version: latest version: latest
name: flowise name: flowise
minio:
backup:
no_stop_required: true
image: quay.io/minio/minio:latest
version: latest
name: minio
redis: redis:
enabled: false enabled: false
database: database:
@@ -73,6 +66,5 @@ docker:
ollama: ai_ollama_models ollama: ai_ollama_models
qdrant: ai_qdrant_data qdrant: ai_qdrant_data
flowise: ai_flowise_data flowise: ai_flowise_data
minio: ai_minio_data
credentials: {} credentials: {}

View File

@@ -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 }}"

View File

@@ -16,7 +16,7 @@
depends_on: depends_on:
- ollama - ollama
ports: ports:
- "127.0.0.1:{{ AI_OPENWEBUI_PORT }}:8080" - "127.0.0.1:{{ AI_OPENWEBUI_PORT_PUBLIC }}:8080"
volumes: volumes:
- openwebui_data:/app/backend/data - openwebui_data:/app/backend/data
{% include 'roles/docker-container/templates/networks.yml.j2' %} {% include 'roles/docker-container/templates/networks.yml.j2' %}
@@ -56,23 +56,11 @@
- qdrant - qdrant
- litellm - litellm
ports: 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: volumes:
- flowise_data:/root/.flowise - flowise_data:/root/.flowise
{% include 'roles/docker-container/templates/networks.yml.j2' %} {% 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/networks.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %} {% include 'roles/docker-compose/templates/volumes.yml.j2' %}
@@ -84,5 +72,3 @@
name: {{ AI_QDRANT_VOLUME }} name: {{ AI_QDRANT_VOLUME }}
flowise_data: flowise_data:
name: {{ AI_FLOWISE_VOLUME }} name: {{ AI_FLOWISE_VOLUME }}
minio_data:
name: {{ AI_MINIO_VOLUME }}

View File

@@ -9,7 +9,7 @@ LITELLM_MASTER_KEY=dummy-key
LITELLM_CONFIG=/etc/litellm/config.yaml LITELLM_CONFIG=/etc/litellm/config.yaml
# Flowise # Flowise
PORT={{ AI_FLOWISE_INTERNAL_PORT }} PORT={{ AI_FLOWISE_PORT_INTERNAL }}
FLOWISE_USERNAME=admin FLOWISE_USERNAME=admin
FLOWISE_PASSWORD=admin FLOWISE_PASSWORD=admin
DATABASE_PATH=/root/.flowise DATABASE_PATH=/root/.flowise
@@ -19,7 +19,3 @@ FLOWISE_FILE_STORAGE_PATH=/root/.flowise/storage
QDRANT_URL={{ AI_QDRANT_INTERNAL_URL }} QDRANT_URL={{ AI_QDRANT_INTERNAL_URL }}
OPENAI_API_BASE={{ AI_LITELLM_INTERNAL_URL }}/v1 OPENAI_API_BASE={{ AI_LITELLM_INTERNAL_URL }}/v1
OPENAI_API_KEY=dummy-key OPENAI_API_KEY=dummy-key
# MINIO
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=adminadmin

View File

@@ -1,6 +1,6 @@
# General # General
application_id: "web-app-ai" application_id: "web-app-ai"
# Docker # Docker
docker_pull_git_repository: false docker_pull_git_repository: false
@@ -8,18 +8,17 @@ docker_compose_file_creation_enabled: true
# Open WebUI # Open WebUI
# https://openwebui.com/ # 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_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_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_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_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_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_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 # Ollama
# https://ollama.com/ # 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_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_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.ollama.image') }}"
AI_OLLAMA_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.ollama.name') }}" 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 # LiteLLM
# https://www.litellm.ai/ # 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_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_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.litellm.image') }}"
AI_LITELLM_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.litellm.name') }}" 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 # Qdrant
# https://qdrant.tech/ # 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_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_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.qdrant.image') }}"
AI_QDRANT_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.qdrant.name') }}" 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 # Flowise
# https://flowiseai.com/ # 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_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_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_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_VOLUME: "{{ applications | get_app_conf(application_id, 'docker.volumes.flowise') }}"
AI_FLOWISE_PUBLIC_PORT: "{{ ports.localhost.http[application_id ~ '_flowise'] }}" AI_FLOWISE_PORT_PUBLIC: "{{ ports.localhost.http[application_id ~ '_flowise'] }}"
AI_FLOWISE_INTERNAL_PORT: 3000 AI_FLOWISE_PORT_INTERNAL: 3000
AI_FLOWISE_DOMAIN: "{{ applications | get_app_conf(application_id, 'server.domains.canonical.flowise') }}"
# 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_FRONT_PROXY_MATRIX: >- AI_FRONT_PROXY_MATRIX: >-
{{ {{
[ [
{ 'domain': server.domains.canonical.openwebui, 'http_port': AI_OPENWEBUI_PORT }, { 'domain': AI_OPENWEBUI_DOMAIN, 'http_port': AI_OPENWEBUI_PORT_PUBLIC },
{ 'domain': server.domains.canonical.flowise, 'http_port': AI_FLOWISE_PUBLIC_PORT }, { 'domain': AI_FLOWISE_DOMAIN, 'http_port': AI_FLOWISE_PORT_PUBLIC }
{ 'domain': server.domains.canonical.minio, 'http_port': AI_MINIO_CONSOLE_PUBLIC_PORT }
] ]
+ (
[ { 'domain': server.domains.canonical.minio_api, 'http_port': AI_MINIO_API_PUBLIC_PORT } ]
if (server.domains.canonical.minio_api is defined) else []
)
}} }}

View File

@@ -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: {}

View File

@@ -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 }}"

View File

@@ -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 }}

View File

@@ -0,0 +1,3 @@
# MINIO
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=adminadmin

View File

@@ -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 }
]
}}