espo-deploy/rmm-tasks/ESPO-03-First-Deploy.sh
Gordon Zimm f1701675ef Version tatsaechlich aus den Vorgabewerten lesen (Nachtrag zu 86bc5d9)
Der vorige Commit hat nur den Kommentar geaendert, der Ersetzungsausdruck griff
nicht. Jetzt lesen alle drei Skripte defaults, config und config-internal in
dieser Reihenfolge; der spaetere Wert gewinnt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-24 16:21:55 +02:00

99 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
# ESPO-03-First-Deploy - richtet EspoCRM auf einer vorbereiteten VM zum ersten Mal ein.
# Aufruf: ESPO-03-First-Deploy.sh <fqdn> <ring>
# Ob der Lauf erlaubt ist, entscheidet der Task selbst per If/Then auf espo_zustand.
# Fuer Aktualisierungen ist der Update-Weg zustaendig. Dass dieser Lauf nur an einer neuen Instanz
# stattfindet, stellt der Task sicher (If/Then auf espo_zustand), nicht das Skript.
set -u
# Standzeile: zeigt im Protokoll, welche Fassung tatsaechlich gelaufen ist.
echo "ESPO-03-First-Deploy, Skriptstand 2026-09-24"
BASIS_URL=https://gitea.subcura.net/EspoCRM_Public/espo-deploy/raw/branch/main
WARTE_MAX=900
FQDN="${1:-}"
RING="${2:-}"
fehler() { echo "FEHLER: $*"; echo "ESPO03_ERGEBNIS: FEHLER"; exit 1; }
# 1. Vorbedingungen - lieber hier abbrechen als auf halbem Weg.
[ "$(id -u)" -eq 0 ] || fehler "nicht als root gestartet"
command -v docker >/dev/null || fehler "Docker fehlt - erst ESPO-02 ausfuehren"
docker info >/dev/null 2>&1 || fehler "Docker laeuft nicht - erst ESPO-02 pruefen"
[ -n "$FQDN" ] || fehler "kein FQDN uebergeben"
[ -n "$RING" ] || fehler "kein Ring uebergeben"
# 2. Verzeichnisse anlegen. Die Eigentuemer setzen die Images beim ersten Start selbst.
install -d -m 0755 /srv/espo /srv/espo/bin /srv/espo/mariadb /srv/espo/data /srv/espo/custom /srv/espo/client-custom
install -d -m 0700 /srv/espo/secrets
# 3. Geheimnisse auf der VM erzeugen - sie stehen in keinem Skript, keiner Ausgabe und keinem Repository.
# Ohne abschliessenden Zeilenumbruch, damit die _FILE-Auswertung der Images genau diesen Wert sieht.
umask 077
for G in db_root_password db_password; do
[ -s "/srv/espo/secrets/$G" ] && continue
printf '%s' "$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32)" > "/srv/espo/secrets/$G"
chmod 0600 "/srv/espo/secrets/$G"
done
umask 022
# 4. Grundeinstellungen bereitlegen, bevor EspoCRM zum ersten Mal startet.
# Sie gehoeren zum Stand des Rings, liegen also im selben Ordner wie die Compose.
# Dieselbe Zuordnung steht in bin/espo-compose-rendern - beide zusammen halten.
case "$RING" in
0) RINGORDNER="0%20-%20intern" ;;
1) RINGORDNER="1%20-%20Pilotkunde" ;;
2) RINGORDNER="2%20-%20Produktivkunde" ;;
*) fehler "unbekannter Ring '$RING' (erwartet 0, 1 oder 2)" ;;
esac
curl -fsSL "$BASIS_URL/docker/$RINGORDNER/config-override.php" -o /srv/espo/data/config-override.php \
|| fehler "config-override.php fuer Ring '$RING' nicht abrufbar"
# 5. Compose aus dem Stand des Rings schreiben.
curl -fsSL "$BASIS_URL/bin/espo-compose-rendern" -o /srv/espo/bin/espo-compose-rendern || fehler "Render-Skript nicht abrufbar"
chmod 0755 /srv/espo/bin/espo-compose-rendern
/srv/espo/bin/espo-compose-rendern "$FQDN" "$RING" || fehler "Compose konnte nicht geschrieben werden"
# 6. Starten. Die Images werden dabei zum ersten Mal geholt.
# --quiet-pull unterdrueckt die Fortschrittszeilen je Schicht; die Ausgabe wird aufgefangen und
# nur im Fehlerfall gezeigt. Sonst ersaeuft der Bericht in tausenden Zeilen (gemessen am 24.09.2026).
START_AUSGABE="$(docker compose -f /srv/espo/docker-compose.yml up -d --quiet-pull 2>&1)" || {
echo "$START_AUSGABE" | tail -n 20
fehler "Start fehlgeschlagen"
}
# 7. Auf die Anwendung warten. Der erste Lauf installiert und baut das Schema auf, das dauert.
ENDE=$(( SECONDS + WARTE_MAX ))
while [ "$SECONDS" -lt "$ENDE" ]; do
[ "$(docker inspect -f '{{.State.Health.Status}}' espocrm 2>/dev/null)" = "healthy" ] && break
sleep 10
done
[ "$(docker inspect -f '{{.State.Health.Status}}' espocrm 2>/dev/null)" = "healthy" ] \
|| fehler "espocrm nach ${WARTE_MAX}s nicht gesund - 'docker logs espocrm' ansehen"
# 8. Ergebnis zeigen. Die Datenbankabfragen laufen im Container und lesen das Passwort dort aus der Secret-Datei,
# damit es weder im Skript noch in der Prozessliste der VM auftaucht.
echo "--- Container"
docker compose -f /srv/espo/docker-compose.yml ps --format 'table {{.Name}}\t{{.Status}}'
echo "--- Instanz"
echo "FQDN: $FQDN (Ring $RING)"
# Die Version steht je nach Stand in config.php oder in config-internal.php - EspoCRM selbst
# fragen ist verlaesslicher als eine der beiden Dateien zu raten.
VERSION="$(docker exec espocrm php -r '$v=""; foreach (["/var/www/html/application/Espo/Resources/defaults/config.php","/var/www/html/data/config.php","/var/www/html/data/config-internal.php"] as $f) { $a=@include $f; if (is_array($a) && !empty($a["version"])) { $v=$a["version"]; } } echo $v;' 2>/dev/null)"
[ -n "$VERSION" ] || VERSION="$(grep -hoP "['\"]version['\"]\s*=>\s*['\"]\K[^'\"]+" /srv/espo/data/config.php /srv/espo/data/config-internal.php 2>/dev/null | head -1)"
echo "Version: ${VERSION:-unbekannt}"
IMAGE="$(docker inspect -f '{{.Config.Image}}' espocrm 2>/dev/null)"
echo "Image: $IMAGE"
echo "Digest: $(docker image inspect --format '{{if .RepoDigests}}{{index .RepoDigests 0}}{{else}}{{.Id}}{{end}}' "$IMAGE" 2>/dev/null)"
DB_ABFRAGE='mariadb -u root -p"$(cat /run/secrets/db_root_password)" -N -B -D espocrm -e'
echo "MariaDB: $(docker exec espocrm-db sh -c "$DB_ABFRAGE \"select version()\"" 2>/dev/null)"
echo "Zeichensatz: $(docker exec espocrm-db sh -c "$DB_ABFRAGE \"select @@character_set_server, @@collation_server\"" 2>/dev/null)"
ID_LAENGE="$(docker exec espocrm-db sh -c "$DB_ABFRAGE \"select length(id) from user limit 1\"" 2>/dev/null)"
echo "ID-Laenge: ${ID_LAENGE:-unbekannt} (36 = UUIDv4 aktiv)"
[ "$ID_LAENGE" = "36" ] || { echo "FEHLER: Record-IDs sind nicht 36 Zeichen lang - recordId.json hat nicht gegriffen"; echo "ESPO03_ERGEBNIS: FEHLER"; exit 1; }
echo "--- Naechster Schritt von Hand"
echo "Admin-Passwort ('admin') in der Instanz aendern, im Passwort-Safe ablegen,"
echo "erst danach DNS-Eintrag und Portfreigabe an der OPNsense setzen."
echo "ESPO03_ERGEBNIS: OK"