# Rolle "infra" (LXC 101 auf pve44, HA nach pve48/pve52): Router, TTS, Postgres und Monitoring in einem Stack. # Kein eigener LiteLLM (D4): Der Router nutzt den LiteLLM mit PSE auf appsrv08 (LITELLM_BASE_URL). # # Lokal: cp .env.example .env && docker compose up -d # Cluster: Ansible-Rolle infra-stack (platform/proxmox/ansible). Zustand und Geheimnisse liegen dort # außerhalb des Repos in KNASTER_STATE_DIR=/opt/knaster/infra (.env, secrets/, file_sd/), Aufruf: # docker compose -p knaster-infra --env-file /opt/knaster/infra/.env -f /deploy/compose/infra/docker-compose.yml up -d name: knaster-infra x-restart: &restart restart: unless-stopped labels: {autoheal: "true"} services: router: <<: *restart build: context: ../../.. dockerfile: deploy/docker/router.Dockerfile image: knaster/router:${KNASTER_VERSION:-dev} env_file: [{path: "${KNASTER_STATE_DIR:-.}/.env", required: false}] environment: KNASTER_DB_URL: postgresql+psycopg://knaster:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD fehlt}@postgres:5432/knaster KNASTER_SITE_DIR: /app/sites/${KNASTER_SITE:-knaster} KNASTER_DRY_RUN: ${KNASTER_DRY_RUN:-true} LITELLM_BASE_URL: ${LITELLM_BASE_URL:?LITELLM_BASE_URL fehlt (LiteLLM auf appsrv08, D4)} ports: ["8080:8080"] depends_on: postgres: {condition: service_healthy} tts-piper: <<: *restart build: context: ../../.. dockerfile: deploy/docker/tts-piper.Dockerfile image: knaster/tts-piper:${KNASTER_VERSION:-dev} container_name: tts-piper environment: KNASTER_TTS_PARALLEL: ${TTS_PARALLEL:-2} # i7 mit 4 Kernen: max. 2 parallele Synthesen ports: ["8090:8090"] deploy: resources: limits: {cpus: "2", memory: 1G} postgres: <<: *restart image: pgvector/pgvector:0.8.7-pg16-trixie environment: POSTGRES_USER: knaster POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD fehlt} POSTGRES_DB: knaster volumes: - postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U knaster -d knaster"] interval: 10s timeout: 5s retries: 5 # --- Monitoring --------------------------------------------------------------------------------- prometheus: <<: *restart image: prom/prometheus:v3.13.4 command: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.path=/prometheus - --storage.tsdb.retention.time=15d - --web.enable-lifecycle volumes: - ../../prometheus:/etc/prometheus:ro # file_sd: Ziele der GPU-VMs (DHCP, IPs wechseln), erzeugt auf ops aus `tofu output -json gpu_vms` - ${KNASTER_STATE_DIR:-.}/file_sd:/etc/knaster-sd:ro - prometheus:/prometheus extra_hosts: ["host.docker.internal:host-gateway"] # node-exporter des LXC läuft im Host-Netz ports: ["9090:9090"] alertmanager: <<: *restart image: prom/alertmanager:v0.34.1 command: - --config.file=/etc/alertmanager/alertmanager.yml - --storage.path=/alertmanager volumes: - ../../alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro - ${KNASTER_STATE_DIR:-.}/secrets/router_token:/etc/alertmanager/router_token:ro - alertmanager:/alertmanager ports: ["9093:9093"] grafana: <<: *restart image: grafana/grafana:12.4.12 environment: GF_SECURITY_ADMIN_USER: admin GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?GRAFANA_ADMIN_PASSWORD fehlt} # wirkt nur beim ersten Start GF_USERS_ALLOW_SIGN_UP: "false" GF_USERS_DEFAULT_THEME: dark GF_ANALYTICS_REPORTING_ENABLED: "false" GF_ANALYTICS_CHECK_FOR_UPDATES: "false" GF_ANALYTICS_CHECK_FOR_PLUGIN_UPDATES: "false" GF_NEWS_NEWS_FEED_ENABLED: "false" GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /var/lib/grafana/dashboards/knaster-uebersicht.json volumes: - ../../grafana/provisioning:/etc/grafana/provisioning:ro - ../../grafana/dashboards:/var/lib/grafana/dashboards:ro - grafana:/var/lib/grafana ports: ["3000:3000"] depends_on: [prometheus] pve-exporter: <<: *restart image: prompve/prometheus-pve-exporter:3.10.1 # Token monitoring@pve!prom (PVEAuditor) als PVE_USER/PVE_TOKEN_NAME/PVE_TOKEN_VALUE/PVE_VERIFY_SSL env_file: [{path: "${KNASTER_STATE_DIR:-.}/secrets/pve-exporter.env", required: false}] expose: ["9221"] node-exporter: <<: *restart image: prom/node-exporter:v1.12.1 command: - --path.rootfs=/host - --web.listen-address=:9100 network_mode: host pid: host volumes: - /:/host:ro # ohne rslave: im unprivilegierten LXC nicht erlaubt autoheal: restart: unless-stopped image: willfarrell/autoheal:1.2.0 environment: AUTOHEAL_CONTAINER_LABEL: autoheal AUTOHEAL_INTERVAL: "15" volumes: - /var/run/docker.sock:/var/run/docker.sock volumes: postgres: {} prometheus: {} alertmanager: {} grafana: {}