diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..cce0a7d --- /dev/null +++ b/compose.yml @@ -0,0 +1,221 @@ +services: + + ########################################################################### + # Initialisiert das persistente Agent-Datenvolume. + # + # Wichtig: + # Kein "chown -R" bei jedem Deployment. Der Agent schreibt anschließend + # selbst als UID/GID 65532, daher genügt normalerweise das Root-Verzeichnis. + ########################################################################### + agent-data-init: + image: alpine:3.22 + user: "0:0" + command: + - sh + - -c + - | + set -eu + mkdir -p /app/data + chown 65532:65532 /app/data + volumes: + - agent-data:/app/data + restart: "no" + + + ########################################################################### + # GLPI AI Agent + ########################################################################### + agent: + image: git.send.nrw/sendnrw/glpi-ai-agent:latest + + restart: unless-stopped + + env_file: + - .env + + ports: + - "${AGENT_PORT:-7080}:7080" + + volumes: + # Persistenter Agent-State: + # - Knowledge-Index + # - Runs/Audit + # - Learning + # - Managed KBs + # - GLPI-KB-Cache + - agent-data:/app/data + + # Gleicher Knowledge-Pfad wie Editor/Search. + - "${KB_DATA_PATH:-./knowledge2}:/app/knowledge:ro" + + depends_on: + agent-data-init: + condition: service_completed_successfully + + # Nur Startreihenfolge. + # Der Agent selbst überwacht Ollama und soll sein WebUI auch dann + # bereitstellen können, wenn Ollama gerade nicht verfügbar ist. + ollama: + condition: service_started + + security_opt: + - no-new-privileges:true + + cap_drop: + - ALL + + read_only: true + + tmpfs: + - /tmp:size=64m,mode=1777 + + + ########################################################################### + # Ollama + ########################################################################### + ollama: + image: ollama/ollama:latest + + restart: unless-stopped + + volumes: + - ollama-data:/root/.ollama + + # ollama CLI spricht dabei mit dem lokalen Ollama-Server. + healthcheck: + test: ["CMD", "ollama", "list"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 30s + + # CPU-Betrieb: + # keine weitere Konfiguration erforderlich. + # + # NVIDIA-Beispiel: + # + # gpus: all + # + # Siehe offizielle Ollama-Docker-Dokumentation. + + + ########################################################################### + # Knowledge Base Editor + ########################################################################### + kb-editor: + image: git.send.nrw/sendnrw/glpi-ai-knowledgebase:latest + + restart: unless-stopped + + ports: + - "${KB_EDITOR_PORT:-7082}:8080" + + environment: + APP_MODE: editor + + APP_TITLE: "${EDITOR_TITLE:-KB Administration}" + APP_SUBTITLE: "${EDITOR_SUBTITLE:-Wissensbasis verwalten}" + + DATA_DIR: /data/knowledge + BACKUP_DIR: /data/backups + + LISTEN_ADDR: :8080 + + BASIC_AUTH_USER: "${EDITOR_AUTH_USER:-}" + BASIC_AUTH_PASSWORD: "${EDITOR_AUTH_PASSWORD:-}" + + AI_FALLBACK_ENABLED: "${AI_FALLBACK_ENABLED:-false}" + + OLLAMA_BASE_URL: "${OLLAMA_BASE_URL:-http://ollama:11434}" + OLLAMA_MODEL: "${OLLAMA_MODEL:-qwen3:8b}" + OLLAMA_TIMEOUT: "${OLLAMA_TIMEOUT:-10m}" + OLLAMA_MAX_CONCURRENT: "${OLLAMA_MAX_CONCURRENT:-1}" + + OLLAMA_STAGING_AUTO_REPLY: "${OLLAMA_STAGING_AUTO_REPLY:-false}" + OLLAMA_STAGING_MIN_SCORE: "${OLLAMA_STAGING_MIN_SCORE:-0.70}" + + volumes: + - "${KB_DATA_PATH:-./knowledge2}:/data/knowledge:rw" + - "${KB_BACKUP_PATH:-./backups}:/data/backups:rw" + - "${KB_STAGING_PATH:-./staging}:/data/staging:rw" + + read_only: true + + tmpfs: + - /tmp:size=32m,mode=1777 + + security_opt: + - no-new-privileges:true + + cap_drop: + - ALL + + + ########################################################################### + # Knowledge Base Search + ########################################################################### + kb-search: + image: git.send.nrw/sendnrw/glpi-ai-knowledgebase:latest + + restart: unless-stopped + + ports: + - "${KB_SEARCH_PORT:-7081}:8080" + + environment: + APP_MODE: google + + APP_TITLE: "${SEARCH_TITLE:-Stadt Hilden - KB-Datenbank}" + APP_SUBTITLE: "${SEARCH_SUBTITLE:-Interne Lösungsdatenbank}" + + AUTO_RELOAD_INTERVAL: "${AUTO_RELOAD_INTERVAL:-60s}" + + DATA_DIR: /data/knowledge + LISTEN_ADDR: :8080 + + BASIC_AUTH_USER: "${SEARCH_AUTH_USER:-}" + BASIC_AUTH_PASSWORD: "${SEARCH_AUTH_PASSWORD:-}" + + AI_FALLBACK_ENABLED: "${AI_FALLBACK_ENABLED:-true}" + + OLLAMA_BASE_URL: "${OLLAMA_BASE_URL:-http://ollama:11434}" + OLLAMA_MODEL: "${OLLAMA_MODEL:-qwen3:8b}" + OLLAMA_TIMEOUT: "${OLLAMA_TIMEOUT:-10m}" + OLLAMA_MAX_CONCURRENT: "${OLLAMA_MAX_CONCURRENT:-1}" + + OLLAMA_STAGING_AUTO_REPLY: "${OLLAMA_STAGING_AUTO_REPLY:-false}" + OLLAMA_STAGING_MIN_SCORE: "${OLLAMA_STAGING_MIN_SCORE:-0.70}" + + volumes: + - "${KB_DATA_PATH:-./knowledge2}:/data/knowledge:ro" + - "${KB_STAGING_PATH:-./staging}:/data/staging:rw" + + # Search funktioniert grundsätzlich auch ohne Editor. + # Deshalb würde ich hier keine harte Startabhängigkeit vom Editor setzen. + + read_only: true + + tmpfs: + - /tmp:size=32m,mode=1777 + + security_opt: + - no-new-privileges:true + + cap_drop: + - ALL + + +############################################################################### +# PERSISTENTE VOLUMES +############################################################################### + +volumes: + + # Expliziter Name verhindert, dass ein geänderter Compose-Projektname + # scheinbar ein neues/leeres Agent-Volume erzeugt. + agent-data: + name: glpi-ai-agent-data + + # Enthält heruntergeladene Ollama-Modelle. + ollama-data: + name: glpi-ai-ollama-data \ No newline at end of file