48e04f36fd
- rsync zum apt-Paket-Block hinzugefügt - DEBIAN_FRONTEND=noninteractive gesetzt (keine debconf-Interaktion) - go PATH-Fix: Debian-spezifische Pfade in /usr/lib/go-*/bin ergänzen (update.sh + install.sh symlink-Fallback) - TLS-Zertifikat: selbstsigniertes RSA-4096 Cert via hostname -f, /etc/ssl/archivmail/ anlegen + Permissions (640, root:archivmail) - nginx: HTTPS von Anfang an (HTTP→HTTPS Redirect + TLS-Block statt HTTP-only) - config.yml-Template vollständig: - smtp.enabled, smtp.domain (hostname -f), smtp.tls_cert/tls_key - imap_server (enabled, bind :993, tls_cert/tls_key) - api.trusted_proxies, api.secure_cookies: true - Vorhandenes config.yml wird nicht überschrieben - systemd archivmail.service: AmbientCapabilities=CAP_NET_BIND_SERVICE (für privilegierten Port 993 als non-root User) NoNewPrivileges=false (erforderlich für AmbientCapabilities) ReadOnlyPaths um /etc/ssl/archivmail ergänzt - systemctl enable am Ende des Installers (ohne --now) - update.sh nach /opt/archivmail/ kopieren + erstes Deployment direkt anstoßen - Abschlussbericht: FQDN, HTTPS/IMAP/SMTP URLs, TLS-Hinweis Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
155 lines
7.1 KiB
Bash
Executable File
155 lines
7.1 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"
|
|
|
|
# ── 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 download
|
|
CGO_ENABLED=1 go build -tags xapian -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"
|
|
|
|
# Xapian-Lockfile entfernen (verhindert DatabaseLockError beim Neustart)
|
|
XAPIAN_LOCK=$(grep -A2 'index:' /etc/archivmail/config.yml 2>/dev/null | awk '/path:/{print $2}')
|
|
if [[ -n "$XAPIAN_LOCK" && -f "$XAPIAN_LOCK/flintlock" ]]; then
|
|
rm -f "$XAPIAN_LOCK/flintlock"
|
|
log "Xapian-Lockfile entfernt"
|
|
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 ─────────────────────────────────────────────────────────
|
|
|
|
sleep 2
|
|
BACKEND_OK=0
|
|
FRONTEND_OK=0
|
|
|
|
systemctl is-active --quiet archivmail && BACKEND_OK=1 || true
|
|
systemctl is-active --quiet archivmail-web && FRONTEND_OK=1 || true
|
|
|
|
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"
|