diff --git a/README.md b/README.md index 980fb37..4dd4143 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,16 @@ Nach dem Start: - Web-UI: `http://:8080` (Port konfigurierbar) - Anmeldung mit dem im Installer angezeigten Admin-Benutzer/Passwort. +## Aktualisieren +```bash +cd project-good/deploy +./update.sh # holt den neuesten Stand aus Git und baut neu +./update.sh --prune # zusätzlich alte Images aufräumen +./update.sh --no-pull # nur neu bauen, ohne git pull +``` +Das Skript ist von überall aufrufbar, nutzt die vorhandene `deploy/.env` und +prüft am Ende, ob das Backend wieder erreichbar ist. + Verwaltung: ```bash cd deploy diff --git a/deploy/update.sh b/deploy/update.sh new file mode 100755 index 0000000..c510dd3 --- /dev/null +++ b/deploy/update.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# +# Project-Good – 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 '?')" + if ! git -C "$REPO_DIR" pull --ff-only; then + error "git pull fehlgeschlagen (lokale Änderungen?)." + echo " Lokalen Stand ansehen: git -C \"$REPO_DIR\" status" + echo " Lokale Änderungen weg: git -C \"$REPO_DIR\" checkout -- ." + 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 )"