Files
ARIA-AGENT/xtts/bootstrap.sh
T
duffyduckandClaude Opus 5.5 32d34f39cd fix(xtts): LLM auf der GPU + Container finden nach dem Reboot den RVS
Zwei Ursachen, beide auf der KI-Box nachgewiesen:

1. llama.cpp fand auch mit Treiber 615 keine Karte ("unsupported display
   driver / cuda driver combination"). Das llama-swap-Image traegt in seiner
   ld.so.conf die eigene CUDA-Kompatibilitaets-libcuda (575) VOR dem vom
   Container-Toolkit eingehaengten Host-Treiber (615) ein. Die Kompatibilitaets-
   bibliothek hilft nur Rechenzentrumskarten; bei GeForce scheitert llama.cpp
   damit — mit aelterem Treiber ("forward compatibility …") wie mit neuerem —
   und rechnet still auf der CPU. Jetzt LD_LIBRARY_PATH mit dem Host-Treiber
   zuerst. Auf der Box getestet: llama.cpp sieht CUDA0 + CUDA1. Whisper und
   F5-TTS (andere Images) sehen ihre Karte mit 615 ohnehin.

2. Nach dem Reboot erreichte kein Container den RVS ("Temporary failure in name
   resolution"). Debian traegt die Netzwerkkarte als allow-hotplug ein; darauf
   wartet network-online.target nicht. Docker startete die Container 2 s nach
   "online", bevor DHCP den DNS-Server lieferte ("DNS resolver has no external
   nameservers"), und die Container behalten diesen leeren Stand. Passiert bei
   jedem Reboot. bootstrap.sh legt jetzt ein systemd-Drop-in an: Docker wartet
   vor dem Start bis zu 90 s auf einen Nameserver in /etc/resolv.conf, dann
   startet es trotzdem. Netzkonfiguration bleibt unangetastet. Escaping und
   beide Pfade (DNS da / nicht da) in einer echten systemd-Unit getestet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:42:06 +02:00

433 lines
20 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# ARIA KI-Box (gpubox) Bootstrap — frisches Debian Trixie → startklarer
# GPU-Satelliten-Host fuer den xtts-Stack (Voxtral/Whisper STT, F5-TTS, lokales LLM).
#
# Ablauf nach `git clone`:
# cd ARIA-AGENT/xtts
# sudo ./bootstrap.sh # richtet Treiber + Docker + NVIDIA-Toolkit ein
# # (falls Treiber frisch installiert: einmal `sudo reboot`, dann Script erneut)
# sudo ./bootstrap.sh --up # dazu: xtts-Stack (Whisper+F5+LLM) hochziehen
#
# Optionen:
# --up am Ende den xtts-Stack starten (Default-Profil, OHNE voxtral)
# --upgrade-driver NVIDIA-Treiber aus NVIDIAs eigener Paketquelle fuer Debian 13
# (Debian selbst hat max. 550 = CUDA 12.4 — zu alt fuer die
# aktuellen llama.cpp/llama-swap-Images, die CUDA 12.8/12.9
# brauchen; ohne Upgrade rechnet das LLM still auf der CPU).
# Spielt erst durch, zeigt den Plan, fragt nach. Danach REBOOT.
# Default-Bootstrap laesst den Treiber unangetastet.
# --yes bei --upgrade-driver nicht nachfragen
# --token <TOK> RVS_TOKEN in xtts/.env eintragen (alternativ: env RVS_TOKEN=...)
# --rvs-host <H> RVS_HOST setzen (Default aus .env.example)
#
# IDEMPOTENT: bereits erledigte Schritte werden uebersprungen. Nach dem
# Treiber-Reboot einfach nochmal ausfuehren — der Rest laeuft dann durch.
#
set -euo pipefail
# ── CLI ──
DO_UP=0
DO_UPGRADE_DRIVER=0
ASSUME_YES=0
RVS_TOKEN_ARG="${RVS_TOKEN:-}"
RVS_HOST_ARG="${RVS_HOST:-}"
while [[ $# -gt 0 ]]; do
case "$1" in
--up) DO_UP=1; shift ;;
--upgrade-driver) DO_UPGRADE_DRIVER=1; shift ;;
--yes|-y) ASSUME_YES=1; shift ;;
--token) RVS_TOKEN_ARG="${2:-}"; shift 2 ;;
--rvs-host) RVS_HOST_ARG="${2:-}"; shift 2 ;;
-h|--help) grep '^#' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) echo "Unbekannte Option: $1"; exit 1 ;;
esac
done
# ── Log-Helfer ──
c_g="\033[1;32m"; c_y="\033[1;33m"; c_r="\033[1;31m"; c_b="\033[1;34m"; c_0="\033[0m"
STEP=0
step() { STEP=$((STEP+1)); echo -e "\n${c_b}[${STEP}] $*${c_0}"; }
ok() { echo -e " ${c_g}✓${c_0} $*"; }
warn() { echo -e " ${c_y}!${c_0} $*"; }
die() { echo -e "${c_r}✗ $*${c_0}" >&2; exit 1; }
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
XTTS_DIR="$REPO_ROOT/xtts"
# ── Preflight ──
[[ "$(id -u)" -eq 0 ]] || die "Bitte als root ausfuehren (sudo ./bootstrap.sh)."
command -v apt-get >/dev/null || die "Kein apt-get — dieses Script ist fuer Debian/Trixie."
export DEBIAN_FRONTEND=noninteractive
echo -e "${c_b}=== ARIA KI-Box Bootstrap ===${c_0}"
echo "Repo: $REPO_ROOT"
echo "xtts: $XTTS_DIR"
# ── 1. Basis-Pakete ──
step "Basis-Pakete"
apt-get update -qq
apt-get install -y -qq ca-certificates curl gnupg git lsb-release >/dev/null
ok "ca-certificates, curl, gnupg, git"
# ── 2. non-free Repos aktivieren (Trixie deb822 + Legacy) ──
step "APT-Komponenten (contrib non-free non-free-firmware)"
# Ergaenzt die drei Komponenten in JEDER Components:-Zeile einer deb822-Datei —
# pro Zeile nur was fehlt, reihenfolge-robust, idempotent. Die Adressen pruefen
# ganze Woerter (non-free-firmware zaehlt NICHT als non-free).
add_components() {
sed -i -E '/^[Cc]omponents:/{
/(^|[[:space:]])contrib([[:space:]]|$)/!s/$/ contrib/
/(^|[[:space:]])non-free([[:space:]]|$)/!s/$/ non-free/
/(^|[[:space:]])non-free-firmware([[:space:]]|$)/!s/$/ non-free-firmware/
}' "$1"
}
ENABLED_ANY=0
shopt -s nullglob
for f in /etc/apt/sources.list.d/*.sources; do
grep -qE '^[Cc]omponents:' "$f" || continue
b="$(md5sum "$f")"; add_components "$f"; a="$(md5sum "$f")"
if [[ "$b" != "$a" ]]; then ENABLED_ANY=1; ok "aktualisiert: $(basename "$f")"; fi
done
shopt -u nullglob
# Legacy /etc/apt/sources.list (deb-Zeilen)
if [[ -f /etc/apt/sources.list ]] && grep -qE '^deb ' /etc/apt/sources.list; then
if ! grep -qE '^deb .*[[:space:]]non-free([[:space:]]|$)' /etc/apt/sources.list; then
sed -i -E '/^deb .*debian/ s/$/ contrib non-free non-free-firmware/' /etc/apt/sources.list
ENABLED_ANY=1; ok "aktualisiert: sources.list"
fi
fi
[[ $ENABLED_ANY -eq 0 ]] && ok "non-free schon aktiv"
apt-get update -qq # immer neu einlesen, damit der Kandidat sicher da ist
# ── 2b. (opt-in) Treiber-Upgrade ueber NVIDIAs Paketquelle fuer Debian 13 ──
# Debian (auch trixie-backports) hat hoechstens 550 = CUDA 12.4. Die aktuellen
# llama.cpp-/llama-swap-Images brauchen CUDA 12.8/12.9 → mit 550 meldet
# llama.cpp "failed to initialize CUDA … forward compatibility …", findet keine
# Karte und rechnet STILL auf der CPU ("ready" meldet es trotzdem).
# NVIDIAs Quelle hat die Pakete unter denselben Namen, nur neuer — apt
# aktualisiert an Ort und Stelle. Alte Debian-Teilpakete (nvidia-driver-bin,
# nvidia-alternative, …) sind in den neuen aufgegangen und werden entfernt.
# Das Container-Toolkit bleibt unberuehrt — ohne es saehe kein Container die GPU,
# darum bricht das Script ab, falls apt es anfassen wollte.
# NUR mit --upgrade-driver, damit ein laufendes Setup nicht ungewollt angefasst wird.
NV_REPO="https://developer.download.nvidia.com/compute/cuda/repos/debian13/x86_64"
MIN_DRIVER_MAJOR=575 # CUDA 12.9 braucht mindestens Treiber 575
# Nachbereitung nach dem Wechsel auf NVIDIAs Pakete. Zwei Stolperfallen, die
# erst bei der echten Installation sichtbar wurden (nicht in apt -s):
# 1. NVIDIAs Paket "nvidia-smi" ist nur noch ein leeres Doku-Paket — das
# Programm (und Bibliotheken, die das Container-Toolkit braucht) steckt in
# "nvidia-driver-cuda". Ohne: kein nvidia-smi, Container ohne GPU.
# 2. /etc/modprobe.d/nvidia.conf (sperrt den freien nouveau-Treiber) war
# vorher ein Verweis ueber das Alternativen-System. Die entfernten
# Altpakete nehmen ihn mit, dpkg legt die neue Datei nur als .dpkg-new ab.
# Ohne Sperre laedt nach dem Reboot nouveau statt nvidia.
# Idempotent — repariert auch eine Box, die schon auf dem neuen Treiber ist.
nv_postfix() {
if ! command -v nvidia-smi >/dev/null 2>&1 && apt-cache show nvidia-driver-cuda >/dev/null 2>&1; then
warn "nvidia-smi fehlt — installiere nvidia-driver-cuda (enthaelt es)"
apt-get install -y nvidia-driver-cuda
fi
find /etc/modprobe.d -maxdepth 1 -name 'nvidia*.conf' -xtype l -print -delete 2>/dev/null \
| sed 's/^/ toter Verweis entfernt: /' || true
if [[ ! -e /etc/modprobe.d/nvidia.conf && -e /etc/modprobe.d/nvidia.conf.dpkg-new ]]; then
mv /etc/modprobe.d/nvidia.conf.dpkg-new /etc/modprobe.d/nvidia.conf
ok "/etc/modprobe.d/nvidia.conf aktiviert (sperrt nouveau)"
NV_INITRAMFS=1
fi
if ! grep -rqs "^blacklist nouveau" /etc/modprobe.d /usr/lib/modprobe.d /lib/modprobe.d; then
mkdir -p /etc/modprobe.d
if printf 'blacklist nouveau\nblacklist nova-core\n' > /etc/modprobe.d/aria-blacklist-nouveau.conf; then
ok "nouveau gesperrt (/etc/modprobe.d/aria-blacklist-nouveau.conf)"
NV_INITRAMFS=1
else
warn "nouveau-Sperre konnte nicht geschrieben werden — nach dem Reboot laedt evtl. nouveau statt nvidia"
fi
fi
if [[ "${NV_INITRAMFS:-0}" -eq 1 ]] || lsmod | grep -q '^nouveau'; then
if update-initramfs -u -k all >/dev/null 2>&1; then
ok "initramfs neu gebaut (Sperre greift schon beim Booten)"
else
warn "update-initramfs fehlgeschlagen — bitte von Hand: update-initramfs -u -k all"
fi
NV_NEED_REBOOT=1
fi
}
if [[ "$DO_UPGRADE_DRIVER" -eq 1 ]]; then
step "NVIDIA-Treiber-Upgrade (NVIDIAs Paketquelle fuer Debian 13)"
CUR="$(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null | head -1 || true)"
if [[ -z "$CUR" ]]; then CUR="$(dpkg-query -W -f='${Version}' nvidia-driver 2>/dev/null || true)"; fi
CUR_MAJOR="${CUR%%.*}"
if [[ "$CUR_MAJOR" =~ ^[0-9]+$ && "$CUR_MAJOR" -ge "$MIN_DRIVER_MAJOR" ]]; then
ok "Treiber ${CUR} ist neu genug (>= ${MIN_DRIVER_MAJOR})"
nv_postfix
if lsmod | grep -q '^nouveau' || ! nvidia-smi >/dev/null 2>&1; then
echo
echo -e "${c_y}==> REBOOT noetig (nouveau ist noch geladen / Treiber noch nicht aktiv):${c_0}"
echo -e "${c_y} sudo reboot → danach: nvidia-smi und cd xtts && docker compose up -d${c_0}"
exit 0
fi
ok "nvidia-smi laeuft, nouveau nicht geladen — alles in Ordnung"
else
ok "aktuell: ${CUR:-kein Treiber} — Ziel: >= ${MIN_DRIVER_MAJOR}"
KEYRING_NEW=0
if ! dpkg -s cuda-keyring >/dev/null 2>&1; then
curl -fsSL "$NV_REPO/cuda-keyring_1.1-1_all.deb" -o /tmp/cuda-keyring.deb \
|| die "NVIDIA-Paketquelle nicht erreichbar ($NV_REPO)"
dpkg -i /tmp/cuda-keyring.deb >/dev/null && KEYRING_NEW=1
ok "NVIDIA-Paketquelle eingetragen"
fi
undo_keyring() { [[ "$KEYRING_NEW" -eq 1 ]] && dpkg -r cuda-keyring >/dev/null 2>&1 && apt-get update -qq || true; }
apt-get update -qq
apt-get install -y -qq linux-headers-amd64 >/dev/null 2>&1 || true
apt-get install -y -qq "linux-headers-$(uname -r)" >/dev/null 2>&1 || true
NV_PKGS="nvidia-driver nvidia-kernel-dkms libcuda1"
# Bei NVIDIA steckt nvidia-smi in nvidia-driver-cuda (das Paket "nvidia-smi"
# ist dort leer). Fallback fuer eine Quelle, die es anders schneidet.
if apt-cache show nvidia-driver-cuda >/dev/null 2>&1; then
NV_PKGS="$NV_PKGS nvidia-driver-cuda"
else
NV_PKGS="$NV_PKGS nvidia-smi"
fi
for p in nvidia-persistenced nvidia-modprobe; do
if dpkg -s "$p" >/dev/null 2>&1; then NV_PKGS="$NV_PKGS $p"; fi
done
# Erst durchspielen — aendert nichts.
if ! SIM="$(apt-get -s install -y $NV_PKGS 2>&1)"; then
echo "$SIM" | grep -E "^E:|Kollidiert|Hängt ab|Depends|Conflicts" | head -15 || true
undo_keyring
die "apt findet keinen sauberen Weg — NICHTS geaendert (Quelle wieder entfernt)."
fi
if echo "$SIM" | grep -qE '^(Remv|Inst) (nvidia-container|libnvidia-container)'; then
undo_keyring
die "Das Upgrade wuerde das NVIDIA-Container-Toolkit anfassen — abgebrochen, NICHTS geaendert."
fi
NEWV="$(echo "$SIM" | sed -nE 's/^Inst nvidia-driver (\[[^]]*\] )?\(([^ ]+).*/\2/p' | head -1 || true)"
echo
echo -e " Plan: Treiber ${CUR:-?} → ${c_g}${NEWV:-?}${c_0}"
echo "$SIM" | grep -E "^[0-9]+ (aktualisiert|upgraded)" | head -1 | sed 's/^/ /' || true
REMV="$(echo "$SIM" | sed -nE 's/^Remv ([^ ]+).*/\1/p' | paste -sd' ' || true)"
if [[ -n "$REMV" ]]; then echo " entfernt (in den neuen Paketen aufgegangen): $REMV"; fi
echo " Container-Toolkit: bleibt unberuehrt"
echo " Danach ist ein REBOOT noetig (neues Kernelmodul)."
if [[ "$ASSUME_YES" -ne 1 && -t 0 ]]; then
read -r -p " Jetzt ausfuehren? [j/N] " ans
if [[ ! "$ans" =~ ^[jJyY] ]]; then
undo_keyring
die "Abgebrochen — NICHTS geaendert."
fi
fi
apt-get install -y $NV_PKGS
dkms autoinstall >/dev/null 2>&1 || true
nv_postfix
GOT="$(dpkg-query -W -f='${Version}' nvidia-driver 2>/dev/null || echo '?')"
[[ "${GOT%%.*}" =~ ^[0-9]+$ && "${GOT%%.*}" -ge "$MIN_DRIVER_MAJOR" ]] \
|| die "Installiert ist ${GOT} — erwartet >= ${MIN_DRIVER_MAJOR}. Bitte Ausgabe oben pruefen."
# -F: der Kernelname enthaelt "+" — als Regex gelesen passte er nie.
# Geprueft wird jeder installierte Kernel (apt kann gerade einen neueren
# mitgebracht haben, der beim Reboot startet).
for k in /lib/modules/*/; do
k="$(basename "$k")"
if [[ -d "/usr/src/linux-headers-$k" ]]; then
if dkms status 2>/dev/null | grep -F "$k" | grep -q installed; then
ok "Kernelmodul fuer $k gebaut"
else
warn "Kernelmodul fuer $k NICHT gebaut — vor dem Reboot: dkms autoinstall -k $k"
fi
fi
done
command -v nvidia-smi >/dev/null 2>&1 || warn "nvidia-smi fehlt nach der Installation — bitte melden"
ok "nvidia-driver ${GOT} installiert"
echo
echo -e "${c_y}==> REBOOT noetig, damit der neue Treiber laedt:${c_0}"
echo -e "${c_y} sudo reboot${c_0}"
echo -e "${c_y} danach: nvidia-smi (zeigt ${GOT%%-*} und eine CUDA-Version >= 12.9)${c_0}"
echo -e "${c_y} und: cd xtts && docker compose up -d${c_0}"
exit 0
fi
fi
# ── 2c. Docker wartet beim Booten auf DNS ──
# Debian traegt die Netzwerkkarte als "allow-hotplug" ein — darauf wartet
# network-online.target NICHT. Docker startet die Container dann, bevor DHCP den
# DNS-Server geliefert hat ("DNS resolver has no external nameservers"), und die
# Container behalten diesen leeren Stand: kein RVS, keine Verbindung, bis man
# sie neu erzeugt. Passiert bei jedem Reboot.
# Abhilfe ohne die Netzkonfiguration anzufassen: Docker wartet vor dem Start bis
# zu 90 s, bis /etc/resolv.conf einen Nameserver hat.
step "Docker wartet beim Booten auf DNS"
DROPIN=/etc/systemd/system/docker.service.d/aria-wait-dns.conf
if [[ -f "$DROPIN" ]]; then
ok "schon eingerichtet ($DROPIN)"
else
mkdir -p "$(dirname "$DROPIN")"
cat > "$DROPIN" <<'EOF'
# ARIA bootstrap.sh: Container erst starten, wenn DNS da ist (sonst merken sie
# sich "keine Nameserver" und erreichen den RVS nie). Siehe xtts/bootstrap.sh.
[Unit]
Wants=network-online.target
After=network-online.target
[Service]
ExecStartPre=/bin/sh -c 'for i in $(seq 1 90); do grep -q "^nameserver" /etc/resolv.conf && exit 0; sleep 1; done; echo "kein DNS nach 90 s — starte trotzdem"; exit 0'
EOF
systemctl daemon-reload
ok "eingerichtet — greift ab dem naechsten Boot"
fi
# ── 3. NVIDIA-Treiber ──
step "NVIDIA-Treiber"
if nvidia-smi >/dev/null 2>&1; then
DRV="$(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null | head -1 || true)"
ok "Treiber ${DRV} aktiv: $(nvidia-smi --query-gpu=name --format=csv,noheader | paste -sd', ')"
DRIVER_ACTIVE=1
# Fuer das lokale LLM zu alt? Dann laeuft es still auf der CPU — das soll man
# hier sehen, nicht erst an einer leeren Karte in nvidia-smi.
PROFILES="$(grep -E '^COMPOSE_PROFILES=' "$XTTS_DIR/.env" 2>/dev/null | cut -d= -f2- || true)"
if [[ "${DRV%%.*}" =~ ^[0-9]+$ && "${DRV%%.*}" -lt "$MIN_DRIVER_MAJOR" && ( -z "$PROFILES" || "$PROFILES" == *llm* ) ]]; then
warn "Treiber ${DRV} ist zu alt fuer das lokale LLM (braucht >= ${MIN_DRIVER_MAJOR})."
warn " Folge: llama.cpp findet keine Karte und rechnet auf der CPU."
warn " Abhilfe: sudo ./bootstrap.sh --upgrade-driver (zeigt erst den Plan, fragt nach)"
fi
else
if dpkg -l | grep -q '^ii nvidia-driver '; then
warn "Treiber installiert, aber nvidia-smi antwortet nicht → REBOOT noetig."
DRIVER_ACTIVE=0
else
# KEIN separater Kandidaten-Check — die apt-cache-Ausgabe ist locale-/pipe-
# fragil (hat faelschlich "kein Kandidat" gemeldet). Der Install IST der Test:
# direkt installieren; schlaegt er fehl, einmal volles apt-get update + Retry,
# dann erst mit Diagnose abbrechen.
# Kernel-Header ZUERST — sonst ueberspringt DKMS den Modulbau ("No kernel
# headers were found") und nvidia-smi kann spaeter nicht mit dem Treiber reden.
warn "Kernel-Header + nvidia-driver installieren (DKMS-Build, dauert)…"
apt-get install -y linux-headers-amd64 || true
apt-get install -y "linux-headers-$(uname -r)" || true
if ! apt-get install -y nvidia-driver firmware-misc-nonfree; then
warn "Install fehlgeschlagen — volles 'apt-get update' + zweiter Versuch…"
apt-get update
if ! apt-get install -y nvidia-driver firmware-misc-nonfree; then
echo
warn "nvidia-driver liess sich nicht installieren. Aktive Quellen:"
grep -rhE '^[Cc]omponents:' /etc/apt/sources.list.d/*.sources 2>/dev/null | sed 's/^/ /' || true
grep -E '^deb ' /etc/apt/sources.list 2>/dev/null | sed 's/^/ /' || true
die "Pruefe 'apt-cache policy nvidia-driver' + Netz/non-free."
fi
fi
# Falls nvidia-kernel-dkms schon (ohne Header) installiert war: Modul jetzt bauen.
dkms autoinstall >/dev/null 2>&1 || true
ok "nvidia-driver + Kernel-Modul installiert"
DRIVER_ACTIVE=0
fi
fi
# ── 4. Docker Engine + Compose-Plugin ──
step "Docker"
if command -v docker >/dev/null 2>&1; then
ok "Docker vorhanden: $(docker --version)"
else
warn "Installiere Docker (offizielles get.docker.com)…"
curl -fsSL https://get.docker.com | sh >/dev/null
systemctl enable --now docker >/dev/null 2>&1 || true
ok "Docker installiert: $(docker --version)"
fi
if docker compose version >/dev/null 2>&1; then
ok "Compose-Plugin: $(docker compose version | head -1)"
else
warn "Compose-Plugin fehlt — installiere docker-compose-plugin…"
apt-get install -y -qq docker-compose-plugin >/dev/null || \
warn "Konnte docker-compose-plugin nicht via apt holen — get.docker.com bringt es normalerweise mit."
fi
# ── 5. NVIDIA Container Toolkit ──
step "NVIDIA Container Toolkit"
NCT_LIST="/etc/apt/sources.list.d/nvidia-container-toolkit.list"
NCT_KEY="/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg"
if ! dpkg -l | grep -q '^ii nvidia-container-toolkit '; then
[[ -f "$NCT_KEY" ]] || curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| gpg --dearmor -o "$NCT_KEY"
if [[ ! -f "$NCT_LIST" ]]; then
curl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed "s#deb https://#deb [signed-by=${NCT_KEY}] https://#g" > "$NCT_LIST"
fi
apt-get update -qq
apt-get install -y -qq nvidia-container-toolkit >/dev/null
ok "nvidia-container-toolkit installiert"
else
ok "nvidia-container-toolkit vorhanden"
fi
# Docker-Runtime auf NVIDIA konfigurieren (idempotent)
if ! grep -q '"nvidia"' /etc/docker/daemon.json 2>/dev/null; then
nvidia-ctk runtime configure --runtime=docker >/dev/null
systemctl restart docker
ok "Docker-Runtime auf NVIDIA konfiguriert + Docker neugestartet"
else
ok "Docker-Runtime bereits NVIDIA-konfiguriert"
fi
# ── 6. xtts/.env vorbereiten ──
step "xtts/.env"
if [[ -f "$XTTS_DIR/.env" ]]; then
ok ".env existiert bereits (unangetastet)"
else
cp "$XTTS_DIR/.env.example" "$XTTS_DIR/.env"
ok ".env aus .env.example erstellt"
fi
if [[ -n "$RVS_TOKEN_ARG" ]]; then
sed -i -E "s#^RVS_TOKEN=.*#RVS_TOKEN=${RVS_TOKEN_ARG}#" "$XTTS_DIR/.env"
ok "RVS_TOKEN eingetragen"
fi
if [[ -n "$RVS_HOST_ARG" ]]; then
sed -i -E "s#^RVS_HOST=.*#RVS_HOST=${RVS_HOST_ARG}#" "$XTTS_DIR/.env"
ok "RVS_HOST=${RVS_HOST_ARG} eingetragen"
fi
if grep -q '^RVS_TOKEN=dein_token_hier' "$XTTS_DIR/.env"; then
warn "RVS_TOKEN ist noch der Platzhalter — vor dem Start setzen:"
warn " nano $XTTS_DIR/.env (oder: sudo ./bootstrap.sh --token <TOKEN>)"
fi
warn "Stimm-Daten (nicht in git): falls von der alten Box noch vorhanden, xtts/voice-id/"
warn " + xtts/voices/ herkopieren. Sonst egal — in der App neu anlegen:"
warn " Sprache neu enrollen (Speaker-ID, sonst fail-open) + F5-Referenz neu hochladen."
# ── 7. GPU-im-Container verifizieren ──
step "GPU-im-Container Test"
if [[ "${DRIVER_ACTIVE:-0}" -eq 1 ]]; then
if docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi >/dev/null 2>&1; then
ok "Docker sieht die GPU — KI-Box ist einsatzbereit."
GPU_READY=1
else
warn "Host-Treiber ok, aber Container sieht die GPU nicht — Toolkit/Runtime pruefen."
GPU_READY=0
fi
else
warn "Treiber noch nicht aktiv → Test uebersprungen."
echo
echo -e "${c_y}==> REBOOT noetig, dann Script erneut ausfuehren:${c_0}"
echo -e "${c_y} sudo reboot && (nach dem Boot) sudo ./bootstrap.sh${c_0}"
exit 0
fi
# ── 8. Optional: xtts-Stack hochziehen ──
if [[ $DO_UP -eq 1 && "${GPU_READY:-0}" -eq 1 ]]; then
step "xtts-Stack starten (Default-Profil: Whisper + F5 + LLM — OHNE voxtral)"
warn "Erster Start laedt Modelle (mehrere GB via HuggingFace) — kann dauern."
( cd "$XTTS_DIR" && docker compose up -d --build )
ok "Stack laeuft. Logs: docker logs -f aria-whisper-bridge"
echo
echo " voxtral (STT via Voxtral) braucht >=16 GB VRAM → erst mit der 24-GB-Karte:"
echo " cd $XTTS_DIR && docker compose stop whisper-bridge && docker compose --profile voxtral up -d --build"
fi
# ── Abschluss ──
echo
echo -e "${c_g}=== Fertig. KI-Box startklar. ===${c_0}"
if [[ $DO_UP -eq 0 ]]; then
echo "Naechster Schritt — Stack starten:"
echo " cd $XTTS_DIR && docker compose up -d --build"
echo "oder direkt: sudo ./bootstrap.sh --up"
fi