#!/usr/bin/env bash # # Vorrania – Update-Skript. # Holt die neueste Version aus Git und baut die Container neu. # # Nutzung (von überall aufrufbar): # ./update.sh Update holen, neu bauen, starten # ./update.sh --prune zusätzlich alte, ungenutzte Images aufräumen # ./update.sh --no-pull nur neu bauen (ohne git pull) # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" ENV_FILE="$SCRIPT_DIR/.env" DO_PULL=1 DO_PRUNE=0 for arg in "$@"; do case "$arg" in --no-pull) DO_PULL=0 ;; --prune) DO_PRUNE=1 ;; -h|--help) sed -n '2,12p' "${BASH_SOURCE[0]}"; exit 0 ;; *) echo "Unbekannte Option: $arg" >&2; exit 1 ;; esac done info() { printf '\033[0;32m==>\033[0m %s\n' "$*"; } warn() { printf '\033[0;33m[!]\033[0m %s\n' "$*"; } error() { printf '\033[0;31m[x]\033[0m %s\n' "$*" >&2; } # --- Docker Compose ermitteln --------------------------------------------- if docker compose version >/dev/null 2>&1; then COMPOSE="docker compose" elif command -v docker-compose >/dev/null 2>&1; then COMPOSE="docker-compose" else error "Docker Compose wurde nicht gefunden." exit 1 fi if [[ ! -f "$ENV_FILE" ]]; then error "Keine .env in $SCRIPT_DIR gefunden. Bitte zuerst ./install.sh ausführen." exit 1 fi # --- Update aus Git holen -------------------------------------------------- if [[ "$DO_PULL" -eq 1 ]]; then if [[ ! -d "$REPO_DIR/.git" ]]; then warn "$REPO_DIR ist kein Git-Repository – überspringe git pull." else info "Hole Updates aus Git …" before="$(git -C "$REPO_DIR" rev-parse --short HEAD 2>/dev/null || echo '?')" # Die Ausgabe wird eingefangen, um die Ursache zu benennen. Frueher hiess # JEDER Fehlschlag "lokale Änderungen?" – bei einem Netzproblem war der # Ratschlag "checkout -- ." dann nicht nur nutzlos, sondern gefaehrlich. if ! pull_ausgabe="$(git -C "$REPO_DIR" pull --ff-only 2>&1)"; then printf '%s\n' "$pull_ausgabe" >&2 remote_url="$(git -C "$REPO_DIR" remote get-url origin 2>/dev/null || echo '?')" # Nur der Rechnername aus der Adresse - den braucht die Fehlersuche. remote_host="$(sed -E 's#^[a-z+]+://##; s#^[^/@]*@##; s#[/:].*$##' <<<"$remote_url")" if grep -qiE 'could not resolve|name or service not known|temporary failure in name resolution' <<<"$pull_ausgabe"; then error "Der Git-Server ist namentlich nicht auflösbar – ein DNS-Problem." echo " Betroffen: $remote_url" echo " Auflösung prüfen: getent hosts $remote_host" echo " Nameserver ansehen: cat /etc/resolv.conf" echo " Deine Dateien sind unberührt – nach dem Beheben einfach erneut starten." elif grep -qiE 'connection refused|connection timed out|network is unreachable|failed to connect|could not read from remote|authentication failed|403 forbidden' <<<"$pull_ausgabe"; then error "Der Git-Server ist nicht erreichbar oder verweigert den Zugriff." echo " Betroffen: $remote_url" echo " Deine Dateien sind unberührt – nach dem Beheben einfach erneut starten." elif grep -qiE 'local changes|would be overwritten|commit your changes|nicht vorspulen|not possible to fast-forward|divergent' <<<"$pull_ausgabe"; then error "git pull fehlgeschlagen – der lokale Stand weicht ab." echo " Lokalen Stand ansehen: git -C \"$REPO_DIR\" status" echo " Lokale Änderungen weg: git -C \"$REPO_DIR\" checkout -- ." else error "git pull fehlgeschlagen. Die Meldung steht oben." echo " Lokalen Stand ansehen: git -C \"$REPO_DIR\" status" fi echo " Ohne Update neu bauen: ./update.sh --no-pull" exit 1 fi after="$(git -C "$REPO_DIR" rev-parse --short HEAD)" if [[ "$before" == "$after" ]]; then info "Bereits aktuell ($after) – baue trotzdem neu." else info "Aktualisiert: $before -> $after" fi fi fi # --- Neu bauen und starten ------------------------------------------------- info "Baue Container neu …" ( cd "$SCRIPT_DIR" && $COMPOSE --env-file "$ENV_FILE" build ) info "Starte Dienste …" ( cd "$SCRIPT_DIR" && $COMPOSE --env-file "$ENV_FILE" up -d ) if [[ "$DO_PRUNE" -eq 1 ]]; then info "Räume ungenutzte Images auf …" docker image prune -f >/dev/null || true fi # --- Kurzer Gesundheitscheck ---------------------------------------------- web_port="$(grep -E '^WEB_PORT=' "$ENV_FILE" | cut -d= -f2-)" web_port="${web_port:-8080}" if command -v curl >/dev/null 2>&1; then info "Warte auf das Backend …" ok=0 for _ in $(seq 1 30); do if curl -fsS "http://localhost:${web_port}/api/health" >/dev/null 2>&1; then ok=1 break fi sleep 2 done if [[ "$ok" -eq 1 ]]; then info "Backend ist erreichbar." else warn "Backend antwortet noch nicht – Logs prüfen:" echo " ( cd \"$SCRIPT_DIR\" && $COMPOSE logs backend --tail=40 )" fi fi echo info "Update fertig." echo " Web-UI: http://localhost:${web_port} (bzw. http://:${web_port})" echo " Status: ( cd \"$SCRIPT_DIR\" && $COMPOSE ps )"