Ampel / ampel (push) Successful in 40s
WAS: Die `devices:`-Eintraege fliegen aus docker-compose.yml. Was dieser Host wirklich hat, ermittelt deploy/geraete-override.sh und schreibt es in docker-compose.override.yml — die zieht Compose von allein dazu, der Befehl bleibt `docker compose up -d`. WARUM (Vorfall heute, 28.08.2026): Das USB-Laufwerk haengt nicht mehr an der VM. Ein ganz normaler Deploy legte daraufhin api, worker UND ui still: Error response from daemon: error gathering device information while adding custom device "/dev/sr0": no such file or directory Ein `devices:`-Eintrag ist eine STARTBEDINGUNG — und keiner der drei Container braucht zum STARTEN ein Laufwerk. Rippy war unten, und die Meldung stand mitten im Build-Rauschen (dieselbe Klasse wie das geschluckte `|| echo` beim .env-Kopieren am 26.07.). DER WIDERSPRUCH WAR AELTER ALS DER VORFALL: install.sh sagt bei fehlendem Laufwerk ausdruecklich "die Installation laeuft trotzdem durch; diese Maschine dient dann als reine KOMPRIMIER-Maschine" — die Compose-Datei sah das anders. Eine Maschine ohne Laufwerk ist ein VORGESEHENER Betriebsfall: der Windows-Worker und der GPU-Encoder sind genau das. Das Skript uebernimmt die Erkennung aus install.sh unveraendert: sr- und sg-Knoten ueber die SCSI-Adresse in /sys abgeglichen, nicht geraten. Und es schreibt die Override AUCH dann, wenn kein Laufwerk da ist — sonst bliebe eine alte Datei mit /dev/sr0 liegen und der Fehler waere derselbe, nur schwerer zu finden, weil sie gitignored ist und in keinem Diff auftaucht. deploy.sh ruft es vor dem Start auf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
113 lines
5.3 KiB
Bash
113 lines
5.3 KiB
Bash
#!/usr/bin/env bash
|
|
# Deploy fuer Rippy — deployt den aktuellen 'main'-Stand auf die Ziel-VM.
|
|
# Single Source of Truth ist 'main' (kein stable-Branch); die Ampel prueft nur,
|
|
# befoerdert nichts. Vor dem Deploy selbst sicherstellen, dass die Ampel fuer den
|
|
# zu deployenden Commit GRUEN ist.
|
|
#
|
|
# Generisch/portabel: Ziel-Host, Repo-URL und .env-Pfad kommen aus der Umgebung —
|
|
# KEINE festen Adressen im Repo. Fuer eine Erst-Installation auf einem eigenen Host
|
|
# reicht ohnehin der einfache Weg (siehe README):
|
|
# git clone <repo> && cd rippy && cp .env.example .env (Werte eintragen)
|
|
# docker compose up -d --build
|
|
#
|
|
# Dieses Skript ist nur die bequeme Remote-Variante: es SSHt zur VM, nutzt dort
|
|
# einen EIGENEN Klon (Default ~/notfall-rippy) und fasst ein evtl. vorhandenes
|
|
# Projektverzeichnis NIE an (git-Klon dort kollidiert mit dessen Sync). Die .env
|
|
# gehoert der VM und wird nur GELESEN (fuer compose-Interpolation).
|
|
#
|
|
# Konfiguration ueber Umgebungsvariablen:
|
|
# RIPPY_VM Ziel-Host fuer ssh, z.B. user@10.0.0.5 (PFLICHT)
|
|
# RIPPY_REPO_URL Git-Repo-URL (branch main) (PFLICHT)
|
|
# RIPPY_ENV_SRC Pfad zur .env auf der VM (Default: ~/rippy/.env)
|
|
# RIPPY_CLONE Arbeits-Klon auf der VM (Default: ~/notfall-rippy)
|
|
# Optionales Argument $1: nur einen Dienst neu bauen, z.B. ./deploy.sh api
|
|
set -euo pipefail
|
|
|
|
VM="${RIPPY_VM:?RIPPY_VM setzen, z.B. RIPPY_VM=user@10.0.0.5}"
|
|
REPO_URL="${RIPPY_REPO_URL:?RIPPY_REPO_URL setzen (Git-URL des Rippy-Repos)}"
|
|
ENV_SRC="${RIPPY_ENV_SRC:-}" # leer -> Remote-Default ~/rippy/.env
|
|
CLONE="${RIPPY_CLONE:-}" # leer -> Remote-Default ~/notfall-rippy
|
|
DIENST="${1:-}"
|
|
|
|
ssh "$VM" bash -s -- "$REPO_URL" "$ENV_SRC" "$CLONE" "$DIENST" <<'REMOTE'
|
|
set -euo pipefail
|
|
REPO_URL="$1"
|
|
ENV_SRC="${2:-$HOME/rippy/.env}"
|
|
CLONE="${3:-$HOME/notfall-rippy}"
|
|
# ⚠️ ${4:-}, nicht "$4" (Befund 26.07.2026): Leere Argumente ueberleben den Weg
|
|
# durch ssh nicht — die Gegenseite bekommt die Befehlszeile als EINEN String und
|
|
# parst sie neu, wobei "" ersatzlos verschwindet. Wer also ohne RIPPY_ENV_SRC,
|
|
# RIPPY_CLONE und ohne Dienst-Argument deployte (der dokumentierte Normalfall!),
|
|
# bekam von 'set -u' nur ein "line 5: $4: unbound variable" und kein Deploy.
|
|
DIENST="${4:-}"
|
|
|
|
# ⚠️ NICHT DEPLOYEN, WÄHREND EIN JOB LÄUFT (Vorfall 26.07.2026, selbst verursacht)
|
|
#
|
|
# `docker compose up -d --build` baut den worker-Container neu — und tötet damit
|
|
# einen laufenden Rip. Genau das ist passiert: mitten in einem Blu-ray-Rip, bei
|
|
# 12 %, nach 5,1 GB. Die Warnung stand im SAVEPOINT und half nichts, weil sie
|
|
# niemand las und nichts sie prüfte. Jetzt prüft es das Skript.
|
|
#
|
|
# Übersteuern mit RIPPY_TROTZDEM=1 — dann ist es eine Entscheidung und kein
|
|
# Versehen.
|
|
if [ -z "${RIPPY_TROTZDEM:-}" ]; then
|
|
ANTWORT="$(curl -s -m 5 http://localhost:8000/health/arbeit 2>/dev/null || true)"
|
|
case "$ANTWORT" in
|
|
*'"arbeit":true'*|*'"arbeit": true'*)
|
|
echo "ABBRUCH: Auf dieser Maschine läuft gerade ein Job." >&2
|
|
echo " Ein Rebuild des worker-Containers würde ihn töten." >&2
|
|
echo "$ANTWORT" | tr ',' '\n' | grep -E '"(status|titel|progress)"' >&2 || true
|
|
echo " Warten, oder bewusst überstimmen: RIPPY_TROTZDEM=1 ./deploy.sh" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [ ! -d "$CLONE/.git" ]; then
|
|
git clone --branch main "$REPO_URL" "$CLONE"
|
|
fi
|
|
cd "$CLONE"
|
|
git fetch origin main
|
|
git reset --hard origin/main
|
|
# ⚠️ Eine fehlende .env-Quelle war bisher eine geschluckte Warnung — und damit
|
|
# eine Falle (Befund 26.07.2026). Auf der Ziel-VM lag die echte .env unter
|
|
# ~/projects/rippy/.env, der Default zeigte auf ~/rippy/.env. Das `cp` schlug
|
|
# also jedes Mal fehl, die Zeile scrollte im Build-Ausgabe-Rauschen vorbei, und
|
|
# gebaut wurde mit der Kopie im Klon: zwei Tage alt, mit einem inzwischen toten
|
|
# MAKEMKV_URL_BASE-Notbehelf und einem JWT_SECRET_KEY aus der Zeit vor dem
|
|
# Auth-Rueckbau. Ergebnis: jeder worker-Build brach ab, und die Ursache stand
|
|
# nirgends.
|
|
if [ -f "$ENV_SRC" ]; then
|
|
cp "$ENV_SRC" .env
|
|
echo "OK: .env aus $ENV_SRC uebernommen."
|
|
elif [ -f .env ]; then
|
|
echo "WARNUNG: $ENV_SRC gibt es nicht — es gilt die .env IM KLON ($CLONE/.env)." >&2
|
|
echo " Stand dieser Datei: $(date -r .env '+%d.%m.%Y %H:%M')" >&2
|
|
echo " Ist das nicht gewollt: RIPPY_ENV_SRC=<pfad> setzen." >&2
|
|
ls -1 "$HOME"/*/.env "$HOME"/*/*/.env 2>/dev/null | head -5 | sed 's/^/ Kandidat: /' >&2 || true
|
|
else
|
|
echo "ABBRUCH: Keine .env — weder unter $ENV_SRC noch im Klon." >&2
|
|
echo " Ohne sie baut compose mit leeren Werten (kein DB-Passwort," >&2
|
|
echo " keine API-Schluessel). RIPPY_ENV_SRC=<pfad> setzen." >&2
|
|
exit 1
|
|
fi
|
|
|
|
sed -i '/^RIPPY_VERSION=/d' .env
|
|
echo "RIPPY_VERSION=$(git rev-parse --short HEAD)" >> .env
|
|
|
|
# Geraete dieses Hosts ermitteln, BEVOR gestartet wird.
|
|
# Ohne diesen Schritt haengt der Start an einem `devices:`-Eintrag, den es
|
|
# vielleicht nicht mehr gibt — am 28.08.2026 legte genau das die ganze
|
|
# Installation stillt, weil das USB-Laufwerk abgezogen war (Herleitung im Kopf
|
|
# von docker-compose.yml). Das Skript schreibt die Override immer neu, auch
|
|
# wenn kein Laufwerk da ist.
|
|
if [ -x ./deploy/geraete-override.sh ]; then
|
|
./deploy/geraete-override.sh .
|
|
else
|
|
echo "WARNUNG: deploy/geraete-override.sh fehlt — starte ohne Geraete-Erkennung."
|
|
fi
|
|
|
|
docker compose -p rippy up -d --build $DIENST
|
|
docker compose -p rippy ps --format 'table {{.Name}}\t{{.Status}}'
|
|
REMOTE
|