systemctl is-active zeigt nur, dass der Prozess läuft — nicht, dass er tatsächlich auf Anfragen antwortet (z.B. bei hängendem DB-Connect). Beide Dienste werden jetzt per HTTP gegen /api/health (Backend) bzw. Port 3000 (Frontend) mit Retry (15x1s) geprüft, bevor das Update als erfolgreich gemeldet wird.
229 lines
11 KiB
Bash
Executable File
229 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
# archivmail Updater
|
|
# Zieht die neueste Version aus Gitea, baut Frontend + Backend und startet Dienste neu.
|
|
#
|
|
# Aufruf (auf dem Server als root):
|
|
# bash /opt/archivmail/update.sh
|
|
#
|
|
# Oder direkt von Gitea laden und ausführen:
|
|
# curl -fsSL https://gitea.perlbach24.de/scripte/archivmail/raw/branch/main/update.sh | bash
|
|
|
|
set -euo pipefail
|
|
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
|
log() { echo -e "${GREEN}[OK]${NC} $*"; }
|
|
info() { echo -e "${BLUE}[..]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[!!]${NC} $*"; }
|
|
die() { echo -e "${RED}[ERR]${NC} $*" >&2; exit 1; }
|
|
|
|
[[ $EUID -eq 0 ]] || die "Bitte als root ausführen: sudo bash update.sh"
|
|
|
|
REPO_URL="${REPO_URL:-https://gitea.perlbach24.de/scripte/archivmail.git}"
|
|
INSTALL_DIR="/opt/archivmail"
|
|
BUILD_DIR="/opt/archivmail/_build"
|
|
FRONTEND_DIR="/opt/archivmail/web"
|
|
BIN_DIR="/opt/archivmail/bin"
|
|
|
|
echo ""
|
|
echo " ╔══════════════════════════════════════╗"
|
|
echo " ║ archivmail Updater ║"
|
|
echo " ╚══════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
# ── Script selbst aktualisieren ──────────────────────────────────────────
|
|
|
|
SCRIPT_URL="https://gitea.perlbach24.de/scripte/archivmail/raw/branch/main/update.sh"
|
|
SELF="$INSTALL_DIR/update.sh"
|
|
if [[ -f "$SELF" ]] && command -v curl >/dev/null; then
|
|
curl -fsSL "$SCRIPT_URL" -o "$SELF.new" 2>/dev/null && mv "$SELF.new" "$SELF" && chmod +x "$SELF" \
|
|
&& info "Script aktualisiert" || rm -f "$SELF.new"
|
|
fi
|
|
|
|
# ── Voraussetzungen prüfen ────────────────────────────────────────────────
|
|
|
|
# Debian legt go nicht immer in /usr/bin — bekannte Pfade ergänzen
|
|
export PATH="$PATH:/usr/local/go/bin:/usr/lib/go/bin"
|
|
for d in /usr/lib/go-*/bin; do export PATH="$PATH:$d"; done
|
|
|
|
command -v git >/dev/null || die "git nicht gefunden"
|
|
command -v node >/dev/null || die "node nicht gefunden"
|
|
command -v npm >/dev/null || die "npm nicht gefunden"
|
|
command -v go >/dev/null || die "go nicht gefunden — apt-get install golang-go"
|
|
|
|
# ── Manticore Search prüfen / installieren ────────────────────────────────
|
|
|
|
if ! command -v searchd >/dev/null 2>&1 && ! systemctl is-active --quiet manticore 2>/dev/null; then
|
|
info "Manticore Search nicht gefunden — installiere..."
|
|
apt-get install -y wget gnupg2 lsb-release 2>/dev/null || true
|
|
MANTICORE_CODENAME=$(lsb_release -cs 2>/dev/null || echo "bookworm")
|
|
wget -q -O /tmp/manticore.deb \
|
|
"https://repo.manticoresearch.com/repository/manticoresearch_${MANTICORE_CODENAME}/pool/main/m/manticoresearch/manticoresearch_6.3.6_amd64.deb" 2>/dev/null \
|
|
|| wget -q -O /tmp/manticore.deb \
|
|
"https://github.com/manticoresoftware/manticoresearch/releases/download/6.3.6/manticoresearch_6.3.6.202408011246.4c39781ba-1+${MANTICORE_CODENAME}_amd64.deb" 2>/dev/null \
|
|
|| true
|
|
if [[ -f /tmp/manticore.deb ]]; then
|
|
dpkg -i /tmp/manticore.deb 2>/dev/null || apt-get install -f -y 2>/dev/null || true
|
|
rm -f /tmp/manticore.deb
|
|
log "Manticore Search installiert"
|
|
else
|
|
warn "Manticore Search konnte nicht automatisch installiert werden — bitte manuell installieren"
|
|
warn "Siehe: https://manticoresearch.com/install/"
|
|
fi
|
|
fi
|
|
|
|
if systemctl list-unit-files manticore.service >/dev/null 2>&1; then
|
|
systemctl enable manticore 2>/dev/null || true
|
|
systemctl is-active --quiet manticore || systemctl start manticore 2>/dev/null || warn "Manticore-Dienst konnte nicht gestartet werden"
|
|
systemctl is-active --quiet manticore && log "Manticore Search läuft"
|
|
fi
|
|
|
|
# ── OCR-Tools (PROJ-35: tesseract + poppler) ──────────────────────────────
|
|
# Optional: ohne diese Tools fällt OCR auf "deaktiviert" zurück, kein Abbruch.
|
|
if ! command -v tesseract >/dev/null 2>&1 || ! command -v pdftotext >/dev/null 2>&1; then
|
|
info "Installiere OCR-Tools (tesseract, poppler-utils)..."
|
|
apt-get install -y tesseract-ocr tesseract-ocr-deu poppler-utils 2>/dev/null || \
|
|
warn "OCR-Tools konnten nicht installiert werden — OCR wird deaktiviert"
|
|
fi
|
|
if command -v tesseract >/dev/null 2>&1 && command -v pdftotext >/dev/null 2>&1; then
|
|
log "OCR-Tools verfügbar (tesseract $(tesseract --version 2>&1 | head -1 | awk '{print $2}'))"
|
|
fi
|
|
|
|
# ── Quellcode holen ───────────────────────────────────────────────────────
|
|
|
|
if [[ -d "$BUILD_DIR/.git" ]]; then
|
|
info "Aktualisiere Quellcode aus Gitea..."
|
|
git config --global --add safe.directory "$BUILD_DIR" 2>/dev/null || true
|
|
git -C "$BUILD_DIR" fetch origin
|
|
git -C "$BUILD_DIR" reset --hard origin/main
|
|
log "Quellcode aktualisiert ($(git -C "$BUILD_DIR" log -1 --format='%h %s'))"
|
|
else
|
|
info "Lade Quellcode von $REPO_URL ..."
|
|
mkdir -p "$BUILD_DIR"
|
|
git clone "$REPO_URL" "$BUILD_DIR"
|
|
log "Quellcode geladen"
|
|
fi
|
|
|
|
# ── Go Backend bauen ──────────────────────────────────────────────────────
|
|
|
|
info "Baue Go Backend..."
|
|
cd "$BUILD_DIR"
|
|
go mod tidy && go mod download
|
|
CGO_ENABLED=0 go build -buildvcs=false -o "$BUILD_DIR/archivmail-new" ./cmd/archivmail/
|
|
log "Go Backend gebaut"
|
|
|
|
# ── Next.js Frontend bauen ────────────────────────────────────────────────
|
|
|
|
info "Installiere Node-Abhängigkeiten..."
|
|
npm ci --prefer-offline 2>/dev/null || npm ci
|
|
log "Node-Abhängigkeiten installiert"
|
|
|
|
info "Baue Next.js Frontend..."
|
|
npm run build
|
|
log "Frontend gebaut"
|
|
|
|
# ── Dienste stoppen ───────────────────────────────────────────────────────
|
|
|
|
info "Stoppe Dienste..."
|
|
systemctl stop archivmail-web 2>/dev/null || warn "archivmail-web nicht aktiv"
|
|
systemctl stop archivmail 2>/dev/null || warn "archivmail nicht aktiv"
|
|
|
|
# ── Manticore als Standard-Backend in config.yml setzen ──────────────────
|
|
CONFIG_FILE="/etc/archivmail/config.yml"
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
# Backend auf manticore umstellen falls noch nicht gesetzt
|
|
if grep -q 'backend:' "$CONFIG_FILE"; then
|
|
if ! grep -q 'backend: manticore' "$CONFIG_FILE"; then
|
|
sed -i 's/^\([[:space:]]*\)backend:.*/\1backend: manticore/' "$CONFIG_FILE"
|
|
info "Index-Backend auf 'manticore' gesetzt"
|
|
fi
|
|
else
|
|
# backend: Zeile unter index: einfuegen
|
|
sed -i '/^index:/a\ backend: manticore' "$CONFIG_FILE"
|
|
info "Index-Backend 'manticore' hinzugefuegt"
|
|
fi
|
|
# manticore_dsn setzen falls nicht vorhanden
|
|
if ! grep -q 'manticore_dsn' "$CONFIG_FILE"; then
|
|
sed -i '/backend: manticore/a\ manticore_dsn: "manticore@tcp(127.0.0.1:9306)/"' "$CONFIG_FILE"
|
|
info "Manticore-DSN gesetzt"
|
|
fi
|
|
log "Manticore-Konfiguration aktualisiert"
|
|
fi
|
|
|
|
# ── Dateien einspielen ────────────────────────────────────────────────────
|
|
|
|
info "Spiele Backend ein..."
|
|
mkdir -p "$BIN_DIR"
|
|
cp "$BUILD_DIR/archivmail-new" "$BIN_DIR/archivmail"
|
|
chmod +x "$BIN_DIR/archivmail"
|
|
# Service-Binary direkt überschreiben (nach systemctl stop)
|
|
cp "$BIN_DIR/archivmail" "$INSTALL_DIR/archivmail"
|
|
ln -sf "$BIN_DIR/archivmail" /usr/local/bin/archivmail
|
|
log "Backend eingespielt"
|
|
|
|
info "Spiele Frontend ein (standalone)..."
|
|
# Next.js standalone mirrors the absolute build path — find the dir that contains server.js.
|
|
# The path is typically: .next/standalone/<build-dir>/server.js
|
|
STANDALONE_SERVER=$(find "$BUILD_DIR/.next/standalone" -maxdepth 3 -name "server.js" | head -1)
|
|
[[ -n "$STANDALONE_SERVER" ]] || die "server.js nicht im standalone-Build gefunden"
|
|
STANDALONE_ROOT=$(dirname "$STANDALONE_SERVER")
|
|
# Clean destination and copy fresh standalone output
|
|
rm -rf "$FRONTEND_DIR"
|
|
mkdir -p "$FRONTEND_DIR"
|
|
rsync -a "$STANDALONE_ROOT/" "$FRONTEND_DIR/"
|
|
# Copy static assets from the full build (standalone doesn't include them)
|
|
mkdir -p "$FRONTEND_DIR/.next/static"
|
|
rsync -a --delete "$BUILD_DIR/.next/static/" "$FRONTEND_DIR/.next/static/"
|
|
if [[ -d "$BUILD_DIR/public" ]]; then
|
|
rsync -a "$BUILD_DIR/public/" "$FRONTEND_DIR/public/"
|
|
fi
|
|
log "Frontend eingespielt"
|
|
|
|
# ── Dienste starten ───────────────────────────────────────────────────────
|
|
|
|
info "Starte Dienste..."
|
|
systemctl start archivmail
|
|
systemctl start archivmail-web
|
|
log "Dienste gestartet"
|
|
|
|
# ── Status prüfen ─────────────────────────────────────────────────────────
|
|
# Hinweis: Kein automatischer Manticore-Reindex mehr bei jedem Update.
|
|
# Neu importierte Mails (IMAP/SMTP/POP3/EML) werden synchron indiziert
|
|
# (siehe internal/imap/importer.go IndexSync) — ein Reindex ist nur nach
|
|
# Schema-Änderungen am Index nötig: manuell mit
|
|
# archivmail reindex --config /etc/archivmail/config.yml
|
|
|
|
BACKEND_OK=0
|
|
FRONTEND_OK=0
|
|
|
|
# Health-Check statt nur systemd-Status: Backend muss tatsächlich auf
|
|
# HTTP antworten (Prozess kann laufen, aber z.B. an DB-Connect hängen).
|
|
info "Prüfe Backend-Health (/api/health)..."
|
|
for i in $(seq 1 15); do
|
|
if systemctl is-active --quiet archivmail && curl -fsS -o /dev/null --max-time 2 http://127.0.0.1:8080/api/health 2>/dev/null; then
|
|
BACKEND_OK=1
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
info "Prüfe Frontend-Health (Port 3000)..."
|
|
for i in $(seq 1 15); do
|
|
if systemctl is-active --quiet archivmail-web && curl -fsS -o /dev/null --max-time 2 http://127.0.0.1:3000/ 2>/dev/null; then
|
|
FRONTEND_OK=1
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo ""
|
|
echo " ┌──────────────────────────────────────┐"
|
|
[[ $BACKEND_OK -eq 1 ]] && echo " │ Backend ✓ läuft │" \
|
|
|| echo " │ Backend ✗ nicht aktiv │"
|
|
[[ $FRONTEND_OK -eq 1 ]] && echo " │ Frontend ✓ läuft │" \
|
|
|| echo " │ Frontend ✗ nicht aktiv │"
|
|
echo " └──────────────────────────────────────┘"
|
|
echo ""
|
|
|
|
[[ $BACKEND_OK -eq 1 && $FRONTEND_OK -eq 1 ]] && log "Update abgeschlossen." \
|
|
|| warn "Ein oder mehrere Dienste sind nicht aktiv. Prüfe: journalctl -u archivmail -u archivmail-web"
|