feat(PROJ-27): Docker-Support + install.sh v2.0 (native + Docker-Modus)
Adds multi-stage Dockerfiles (Go+Xapian CGO, Next.js standalone), docker-compose.yml, webhook-basierter Deploy-Flow und erweitertes install.sh mit interaktiver Modus-Auswahl. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+538
-220
@@ -1,8 +1,11 @@
|
||||
#!/bin/bash
|
||||
# archivmail Server-Installer
|
||||
# archivmail Installer
|
||||
# Unterstützte Systeme: Debian 12 / 13
|
||||
# Aufruf: bash install.sh
|
||||
# Mit eigenem DB-Passwort: DB_PASSWORD=geheim bash install.sh
|
||||
#
|
||||
# Aufruf:
|
||||
# bash install.sh # Interaktiv (Modus-Auswahl)
|
||||
# INSTALL_MODE=native bash install.sh # Nativ (systemd, direkter Build)
|
||||
# INSTALL_MODE=docker bash install.sh # Docker (alle Abhängigkeiten im Container)
|
||||
|
||||
set -euo pipefail
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
@@ -15,8 +18,11 @@ die() { echo -e "${RED}[ERR]${NC} $*" >&2; exit 1; }
|
||||
|
||||
[[ $EUID -eq 0 ]] || die "Bitte als root ausführen: sudo bash install.sh"
|
||||
|
||||
# ── Gemeinsame Variablen ──────────────────────────────────────────────────────
|
||||
DB_PASSWORD="${DB_PASSWORD:-$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)}"
|
||||
API_SECRET="${API_SECRET:-$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 64)}"
|
||||
WEBHOOK_SECRET="${WEBHOOK_SECRET:-$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 40)}"
|
||||
|
||||
INSTALL_DIR="/opt/archivmail"
|
||||
STORE_DIR="/var/archivmail"
|
||||
LOG_DIR="/var/log/archivmail"
|
||||
@@ -24,106 +30,444 @@ CONFIG_DIR="/etc/archivmail"
|
||||
SSL_DIR="/etc/ssl/archivmail"
|
||||
AM_USER="archivmail"
|
||||
FQDN="$(hostname -f 2>/dev/null || hostname)"
|
||||
REPO_URL="${REPO_URL:-https://gitea.perlbach24.de/scripte/archivmail.git}"
|
||||
REPO_URL="${REPO_URL:-https://github.com/yourorg/archivmail.git}"
|
||||
|
||||
# ── Banner ────────────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo " ╔══════════════════════════════════════╗"
|
||||
echo " ║ archivmail Installer v1.1 ║"
|
||||
echo " ╚══════════════════════════════════════╝"
|
||||
echo " ╔══════════════════════════════════════════╗"
|
||||
echo " ║ archivmail Installer v2.0 ║"
|
||||
echo " ╚══════════════════════════════════════════╝"
|
||||
echo ""
|
||||
info "Hostname: $FQDN"
|
||||
echo ""
|
||||
|
||||
# ── 1. Pakete ─────────────────────────────────────────────────────────────────
|
||||
info "Installiere Systempakete..."
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq \
|
||||
golang-go nodejs npm postgresql nginx \
|
||||
libxapian-dev pkg-config build-essential \
|
||||
curl git rsync logrotate openssl
|
||||
log "Pakete installiert"
|
||||
# ── Modus-Auswahl ─────────────────────────────────────────────────────────────
|
||||
INSTALL_MODE="${INSTALL_MODE:-}"
|
||||
|
||||
# go im PATH sicherstellen (Debian legt binary nicht immer in /usr/bin)
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
GO_BIN=$(find /usr/lib/go-*/bin /usr/local/go/bin -name "go" 2>/dev/null | head -1)
|
||||
[[ -n "$GO_BIN" ]] || die "go binary nicht gefunden nach Installation"
|
||||
ln -sf "$GO_BIN" /usr/local/bin/go
|
||||
log "go binary verlinkt: $GO_BIN → /usr/local/bin/go"
|
||||
fi
|
||||
log "go $(go version | awk '{print $3}')"
|
||||
|
||||
# ── 2. Systembenutzer ─────────────────────────────────────────────────────────
|
||||
info "Lege Systembenutzer '$AM_USER' an..."
|
||||
id "$AM_USER" &>/dev/null \
|
||||
&& log "Benutzer '$AM_USER' existiert bereits" \
|
||||
|| { useradd --system --shell /bin/false --home "$STORE_DIR" --create-home "$AM_USER"; log "Benutzer angelegt"; }
|
||||
|
||||
# ── 3. Verzeichnisstruktur ────────────────────────────────────────────────────
|
||||
info "Erstelle Verzeichnisstruktur..."
|
||||
mkdir -p "$STORE_DIR/store" "$STORE_DIR/astore" "$STORE_DIR/xapian"
|
||||
mkdir -p "$CONFIG_DIR" "$LOG_DIR" "$INSTALL_DIR" "$INSTALL_DIR/web" "$SSL_DIR"
|
||||
chown -R "$AM_USER:$AM_USER" "$STORE_DIR" "$LOG_DIR"
|
||||
chmod 755 "$STORE_DIR"
|
||||
chmod 700 "$STORE_DIR/store" "$STORE_DIR/astore" "$STORE_DIR/xapian"
|
||||
log "Verzeichnisse erstellt"
|
||||
|
||||
# ── 4. Keyfile ────────────────────────────────────────────────────────────────
|
||||
info "Generiere Verschlüsselungs-Keyfile..."
|
||||
if [ ! -f "$CONFIG_DIR/keyfile" ]; then
|
||||
openssl rand -base64 32 > "$CONFIG_DIR/keyfile"
|
||||
chmod 400 "$CONFIG_DIR/keyfile"
|
||||
chown "$AM_USER:$AM_USER" "$CONFIG_DIR/keyfile"
|
||||
log "Keyfile generiert: $CONFIG_DIR/keyfile"
|
||||
else
|
||||
log "Keyfile existiert bereits – wird nicht überschrieben"
|
||||
if [[ -z "$INSTALL_MODE" ]]; then
|
||||
echo " Installations-Modus wählen:"
|
||||
echo ""
|
||||
echo " 1) Nativ — Go/Node.js direkt auf dem Server kompiliert und gebaut"
|
||||
echo " (systemd-Dienste, PostgreSQL lokal, kein Docker nötig)"
|
||||
echo ""
|
||||
echo " 2) Docker — Alle Abhängigkeiten (Go, Xapian, Node.js, PostgreSQL)"
|
||||
echo " laufen in Containern. Kein Build-Toolchain auf dem Host."
|
||||
echo " Deployment via GitHub Webhook (git pull → docker compose up)"
|
||||
echo ""
|
||||
read -rp " Auswahl [1/2]: " _choice
|
||||
case "$_choice" in
|
||||
1) INSTALL_MODE="native" ;;
|
||||
2) INSTALL_MODE="docker" ;;
|
||||
*) die "Ungültige Auswahl: $_choice" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ── 5. TLS-Zertifikat ─────────────────────────────────────────────────────────
|
||||
info "Erstelle selbstsigniertes TLS-Zertifikat..."
|
||||
if [ ! -f "$SSL_DIR/archivmail.crt" ]; then
|
||||
SERVER_IP="$(hostname -I | awk '{print $1}')"
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
|
||||
-keyout "$SSL_DIR/archivmail.key" \
|
||||
-out "$SSL_DIR/archivmail.crt" \
|
||||
-subj "/CN=${FQDN}/O=archivmail/C=DE" \
|
||||
-addext "subjectAltName=DNS:${FQDN},DNS:$(hostname -s),IP:${SERVER_IP}" \
|
||||
2>/dev/null
|
||||
chmod 640 "$SSL_DIR/archivmail.key"
|
||||
chmod 644 "$SSL_DIR/archivmail.crt"
|
||||
chown "root:$AM_USER" "$SSL_DIR/archivmail.key"
|
||||
log "TLS-Zertifikat erstellt: $SSL_DIR/archivmail.crt (FQDN: $FQDN, IP: $SERVER_IP)"
|
||||
else
|
||||
log "TLS-Zertifikat existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
[[ "$INSTALL_MODE" == "native" || "$INSTALL_MODE" == "docker" ]] \
|
||||
|| die "INSTALL_MODE muss 'native' oder 'docker' sein (aktuell: $INSTALL_MODE)"
|
||||
|
||||
# ── 6. PostgreSQL ─────────────────────────────────────────────────────────────
|
||||
info "Richte PostgreSQL ein..."
|
||||
systemctl enable postgresql --quiet
|
||||
systemctl start postgresql
|
||||
echo ""
|
||||
info "Modus: $INSTALL_MODE"
|
||||
echo ""
|
||||
|
||||
# Falls config.yml schon existiert, DB-Passwort daraus lesen (verhindert Passwort-Mismatch bei Re-Install)
|
||||
if [ -f "$CONFIG_DIR/config.yml" ]; then
|
||||
EXISTING_PW=$(grep -A5 '^database:' "$CONFIG_DIR/config.yml" | awk '/password:/{print $2}' | head -1)
|
||||
[[ -n "$EXISTING_PW" ]] && DB_PASSWORD="$EXISTING_PW" && info "DB-Passwort aus vorhandener config.yml übernommen"
|
||||
fi
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# DOCKER-INSTALLATION
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
install_docker() {
|
||||
|
||||
su -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='archivmail'\" | grep -q 1 \
|
||||
&& psql -c \"ALTER USER archivmail WITH PASSWORD '$DB_PASSWORD'\" \
|
||||
|| psql -c \"CREATE USER archivmail WITH PASSWORD '$DB_PASSWORD'\"" postgres
|
||||
su -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='archivmail'\" | grep -q 1 || \
|
||||
psql -c \"CREATE DATABASE archivmail OWNER archivmail\"" postgres
|
||||
# GitHub-Repo abfragen wenn nicht gesetzt
|
||||
if [[ "$REPO_URL" == *"yourorg"* ]]; then
|
||||
read -rp " GitHub-Repository URL (z.B. https://github.com/org/archivmail.git): " REPO_URL
|
||||
[[ -n "$REPO_URL" ]] || die "Kein Repository angegeben."
|
||||
fi
|
||||
|
||||
su -c "psql archivmail -c \"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO archivmail;\"" postgres
|
||||
su -c "psql archivmail -c \"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO archivmail;\"" postgres
|
||||
su -c "psql archivmail -c \"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO archivmail;\"" postgres
|
||||
su -c "psql archivmail -c \"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO archivmail;\"" postgres
|
||||
# ── Docker installieren ───────────────────────────────────────────────────
|
||||
info "Installiere Docker..."
|
||||
if command -v docker &>/dev/null; then
|
||||
log "Docker bereits installiert: $(docker --version)"
|
||||
else
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq ca-certificates curl gnupg
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
||||
> /etc/apt/sources.list.d/docker.list
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
systemctl enable --now docker
|
||||
log "Docker $(docker --version) installiert"
|
||||
fi
|
||||
|
||||
log "PostgreSQL eingerichtet"
|
||||
log "Standard-Benutzer werden beim ersten Daemon-Start angelegt"
|
||||
# ── Hilfspakete ───────────────────────────────────────────────────────────
|
||||
info "Installiere Hilfspakete..."
|
||||
apt-get install -y -qq git curl nginx openssl logrotate
|
||||
log "Pakete installiert"
|
||||
|
||||
# ── 7. Konfiguration ──────────────────────────────────────────────────────────
|
||||
info "Erstelle Konfigurationsdatei..."
|
||||
if [ ! -f "$CONFIG_DIR/config.yml" ]; then
|
||||
# ── webhook-Binary (adnanh/webhook) ──────────────────────────────────────
|
||||
info "Installiere webhook-Empfänger..."
|
||||
if ! command -v webhook &>/dev/null; then
|
||||
WEBHOOK_BIN_VERSION="2.8.2"
|
||||
_arch="$(dpkg --print-architecture)"
|
||||
[[ "$_arch" == "amd64" ]] && _arch="linux_amd64"
|
||||
[[ "$_arch" == "arm64" ]] && _arch="linux_arm64"
|
||||
curl -fsSL \
|
||||
"https://github.com/adnanh/webhook/releases/download/${WEBHOOK_BIN_VERSION}/webhook-${_arch}.tar.gz" \
|
||||
| tar -xz -C /usr/local/bin --strip-components=1 "webhook-${_arch}/webhook"
|
||||
chmod +x /usr/local/bin/webhook
|
||||
log "webhook ${WEBHOOK_BIN_VERSION} installiert"
|
||||
else
|
||||
log "webhook bereits installiert"
|
||||
fi
|
||||
|
||||
# ── Verzeichnisse ─────────────────────────────────────────────────────────
|
||||
info "Erstelle Verzeichnisse..."
|
||||
mkdir -p "$CONFIG_DIR" "$LOG_DIR"
|
||||
log "Verzeichnisse erstellt"
|
||||
|
||||
# ── Repository klonen ─────────────────────────────────────────────────────
|
||||
info "Klone Repository..."
|
||||
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
||||
log "Repository existiert bereits — git pull"
|
||||
git -C "$INSTALL_DIR" pull origin main
|
||||
else
|
||||
git clone "$REPO_URL" "$INSTALL_DIR"
|
||||
log "Repository geklont: $INSTALL_DIR"
|
||||
fi
|
||||
|
||||
# ── Keyfile ───────────────────────────────────────────────────────────────
|
||||
info "Generiere Verschlüsselungs-Keyfile..."
|
||||
if [[ ! -f "$CONFIG_DIR/keyfile" ]]; then
|
||||
openssl rand -base64 32 > "$CONFIG_DIR/keyfile"
|
||||
chmod 400 "$CONFIG_DIR/keyfile"
|
||||
log "Keyfile generiert: $CONFIG_DIR/keyfile"
|
||||
else
|
||||
log "Keyfile existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── TLS-Zertifikat ────────────────────────────────────────────────────────
|
||||
info "Erstelle selbstsigniertes TLS-Zertifikat..."
|
||||
mkdir -p "$SSL_DIR"
|
||||
if [[ ! -f "$SSL_DIR/archivmail.crt" ]]; then
|
||||
SERVER_IP="$(hostname -I | awk '{print $1}')"
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
|
||||
-keyout "$SSL_DIR/archivmail.key" \
|
||||
-out "$SSL_DIR/archivmail.crt" \
|
||||
-subj "/CN=${FQDN}/O=archivmail/C=DE" \
|
||||
-addext "subjectAltName=DNS:${FQDN},DNS:$(hostname -s),IP:${SERVER_IP}" \
|
||||
2>/dev/null
|
||||
chmod 640 "$SSL_DIR/archivmail.key"
|
||||
chmod 644 "$SSL_DIR/archivmail.crt"
|
||||
log "TLS-Zertifikat erstellt"
|
||||
else
|
||||
log "TLS-Zertifikat existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── config.yml aus Vorlage ────────────────────────────────────────────────
|
||||
info "Erstelle Konfigurationsdatei..."
|
||||
if [[ ! -f "$CONFIG_DIR/config.yml" ]]; then
|
||||
sed \
|
||||
-e "s/CHANGE_ME_DB_PASSWORD/$DB_PASSWORD/g" \
|
||||
-e "s/CHANGE_ME_64_CHAR_SECRET/$API_SECRET/g" \
|
||||
-e "s/mail\.example\.com/$FQDN/g" \
|
||||
"$INSTALL_DIR/config/config.docker.yml.example" \
|
||||
> "$CONFIG_DIR/config.yml"
|
||||
chmod 640 "$CONFIG_DIR/config.yml"
|
||||
log "config.yml erstellt: $CONFIG_DIR/config.yml"
|
||||
else
|
||||
log "config.yml existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── .env für docker-compose ───────────────────────────────────────────────
|
||||
info "Erstelle .env..."
|
||||
if [[ ! -f "$INSTALL_DIR/.env" ]]; then
|
||||
printf 'DB_PASSWORD=%s\n' "$DB_PASSWORD" > "$INSTALL_DIR/.env"
|
||||
chmod 600 "$INSTALL_DIR/.env"
|
||||
log ".env erstellt"
|
||||
else
|
||||
log ".env existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── deploy.sh ausführbar ──────────────────────────────────────────────────
|
||||
chmod +x "$INSTALL_DIR/scripts/deploy.sh"
|
||||
|
||||
# ── logrotate ─────────────────────────────────────────────────────────────
|
||||
cat > /etc/logrotate.d/archivmail <<EOF
|
||||
${LOG_DIR}/deploy.log {
|
||||
weekly
|
||||
rotate 12
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
}
|
||||
EOF
|
||||
log "logrotate konfiguriert"
|
||||
|
||||
# ── webhook systemd-Dienst ────────────────────────────────────────────────
|
||||
info "Richte webhook-Dienst ein..."
|
||||
cat > /etc/systemd/system/archivmail-webhook.service <<EOF
|
||||
[Unit]
|
||||
Description=archivmail GitHub Webhook Receiver
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=$INSTALL_DIR
|
||||
Environment="WEBHOOK_SECRET=$WEBHOOK_SECRET"
|
||||
Environment="INSTALL_DIR=$INSTALL_DIR"
|
||||
ExecStart=/usr/local/bin/webhook \\
|
||||
-hooks $INSTALL_DIR/scripts/webhook-hooks.json \\
|
||||
-port 9000 \\
|
||||
-ip 127.0.0.1 \\
|
||||
-verbose
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now archivmail-webhook
|
||||
log "archivmail-webhook Dienst gestartet"
|
||||
|
||||
# ── nginx ─────────────────────────────────────────────────────────────────
|
||||
info "Konfiguriere nginx..."
|
||||
cat > /etc/nginx/sites-available/archivmail <<EOF
|
||||
# HTTP → HTTPS Redirect
|
||||
server {
|
||||
listen 80;
|
||||
server_name ${FQDN} _;
|
||||
return 301 https://\$host\$request_uri;
|
||||
}
|
||||
|
||||
# HTTPS
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name ${FQDN} _;
|
||||
|
||||
ssl_certificate ${SSL_DIR}/archivmail.crt;
|
||||
ssl_certificate_key ${SSL_DIR}/archivmail.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header X-Frame-Options SAMEORIGIN always;
|
||||
|
||||
# GitHub Webhook
|
||||
location /hooks/ {
|
||||
proxy_pass http://127.0.0.1:9000/hooks/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# Go API
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
client_max_body_size 512M;
|
||||
}
|
||||
|
||||
# Next.js Frontend
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
access_log /var/log/nginx/archivmail.access.log;
|
||||
error_log /var/log/nginx/archivmail.error.log;
|
||||
}
|
||||
EOF
|
||||
ln -sf /etc/nginx/sites-available/archivmail /etc/nginx/sites-enabled/archivmail
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t && systemctl enable --now nginx && systemctl reload nginx
|
||||
log "nginx konfiguriert"
|
||||
|
||||
# ── Docker Compose Stack starten ──────────────────────────────────────────
|
||||
info "Baue und starte Docker Compose Stack..."
|
||||
cd "$INSTALL_DIR"
|
||||
docker compose up -d --build
|
||||
log "Stack gestartet"
|
||||
|
||||
# ── Zusammenfassung speichern ─────────────────────────────────────────────
|
||||
local summary_file="$CONFIG_DIR/install-summary.txt"
|
||||
cat > "$summary_file" <<EOF
|
||||
archivmail Docker-Installation — $(date '+%d.%m.%Y %H:%M:%S')
|
||||
Server: $FQDN
|
||||
|
||||
=== ZUGANGSDATEN ===
|
||||
|
||||
Datenbank (PostgreSQL im Container):
|
||||
Passwort: $DB_PASSWORD
|
||||
|
||||
API-Secret (JWT + AES):
|
||||
Secret: $API_SECRET
|
||||
|
||||
GitHub Webhook:
|
||||
Secret: $WEBHOOK_SECRET
|
||||
|
||||
Web-Logins werden beim ersten Container-Start angelegt.
|
||||
Passwörter: docker logs archivmail | grep -E 'admin|auditor'
|
||||
|
||||
=== DIENSTE ===
|
||||
|
||||
Web: https://$FQDN
|
||||
SMTP: $FQDN:2525
|
||||
IMAP: $FQDN:1143 (nginx → TLS)
|
||||
|
||||
=== GITHUB WEBHOOK EINRICHTEN ===
|
||||
|
||||
URL: https://$FQDN/hooks/deploy
|
||||
Content-Type: application/json
|
||||
Secret: $WEBHOOK_SECRET
|
||||
Events: Just the push event (refs/heads/main)
|
||||
|
||||
=== DATEIPFADE ===
|
||||
|
||||
Konfiguration: $CONFIG_DIR/config.yml
|
||||
Keyfile: $CONFIG_DIR/keyfile (NIEMALS löschen!)
|
||||
TLS-Cert: $SSL_DIR/archivmail.crt
|
||||
Repository: $INSTALL_DIR
|
||||
Deploy-Log: $LOG_DIR/deploy.log
|
||||
|
||||
=== NÜTZLICHE BEFEHLE ===
|
||||
|
||||
docker compose -f $INSTALL_DIR/docker-compose.yml logs -f
|
||||
docker compose -f $INSTALL_DIR/docker-compose.yml ps
|
||||
bash $INSTALL_DIR/scripts/deploy.sh # Manueller Deploy
|
||||
EOF
|
||||
chmod 600 "$summary_file"
|
||||
log "Zusammenfassung: $summary_file"
|
||||
|
||||
# ── Abschluss ─────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo " ╔══════════════════════════════════════════════════════════════╗"
|
||||
echo " ║ Docker-Installation abgeschlossen! ║"
|
||||
echo " ╚══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
log "archivmail läuft unter: https://$FQDN"
|
||||
echo ""
|
||||
warn "GitHub Webhook jetzt einrichten:"
|
||||
echo " URL: https://$FQDN/hooks/deploy"
|
||||
echo " Content-Type: application/json"
|
||||
echo " Secret: $WEBHOOK_SECRET"
|
||||
echo " Events: Push (nur main-Branch)"
|
||||
echo ""
|
||||
warn "Initial-Passwörter: docker logs archivmail | grep -E 'admin|auditor'"
|
||||
warn "Zusammenfassung: $CONFIG_DIR/install-summary.txt"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# NATIVE INSTALLATION (systemd, direkter Build)
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
install_native() {
|
||||
|
||||
# ── 1. Pakete ─────────────────────────────────────────────────────────────
|
||||
info "Installiere Systempakete..."
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq \
|
||||
golang-go nodejs npm postgresql nginx \
|
||||
libxapian-dev pkg-config build-essential \
|
||||
curl git rsync logrotate openssl
|
||||
log "Pakete installiert"
|
||||
|
||||
# go im PATH sicherstellen (Debian legt binary nicht immer in /usr/bin)
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
GO_BIN=$(find /usr/lib/go-*/bin /usr/local/go/bin -name "go" 2>/dev/null | head -1)
|
||||
[[ -n "$GO_BIN" ]] || die "go binary nicht gefunden nach Installation"
|
||||
ln -sf "$GO_BIN" /usr/local/bin/go
|
||||
log "go binary verlinkt: $GO_BIN → /usr/local/bin/go"
|
||||
fi
|
||||
log "go $(go version | awk '{print $3}')"
|
||||
|
||||
# ── 2. Systembenutzer ─────────────────────────────────────────────────────
|
||||
info "Lege Systembenutzer '$AM_USER' an..."
|
||||
id "$AM_USER" &>/dev/null \
|
||||
&& log "Benutzer '$AM_USER' existiert bereits" \
|
||||
|| { useradd --system --shell /bin/false --home "$STORE_DIR" --create-home "$AM_USER"; log "Benutzer angelegt"; }
|
||||
|
||||
# ── 3. Verzeichnisstruktur ────────────────────────────────────────────────
|
||||
info "Erstelle Verzeichnisstruktur..."
|
||||
mkdir -p "$STORE_DIR/store" "$STORE_DIR/astore" "$STORE_DIR/xapian"
|
||||
mkdir -p "$CONFIG_DIR" "$LOG_DIR" "$INSTALL_DIR" "$INSTALL_DIR/web" "$SSL_DIR"
|
||||
chown -R "$AM_USER:$AM_USER" "$STORE_DIR" "$LOG_DIR"
|
||||
chmod 755 "$STORE_DIR"
|
||||
chmod 700 "$STORE_DIR/store" "$STORE_DIR/astore" "$STORE_DIR/xapian"
|
||||
log "Verzeichnisse erstellt"
|
||||
|
||||
# ── 4. Keyfile ────────────────────────────────────────────────────────────
|
||||
info "Generiere Verschlüsselungs-Keyfile..."
|
||||
if [ ! -f "$CONFIG_DIR/keyfile" ]; then
|
||||
openssl rand -base64 32 > "$CONFIG_DIR/keyfile"
|
||||
chmod 400 "$CONFIG_DIR/keyfile"
|
||||
chown "$AM_USER:$AM_USER" "$CONFIG_DIR/keyfile"
|
||||
log "Keyfile generiert: $CONFIG_DIR/keyfile"
|
||||
else
|
||||
log "Keyfile existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── 5. TLS-Zertifikat ─────────────────────────────────────────────────────
|
||||
info "Erstelle selbstsigniertes TLS-Zertifikat..."
|
||||
if [ ! -f "$SSL_DIR/archivmail.crt" ]; then
|
||||
SERVER_IP="$(hostname -I | awk '{print $1}')"
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
|
||||
-keyout "$SSL_DIR/archivmail.key" \
|
||||
-out "$SSL_DIR/archivmail.crt" \
|
||||
-subj "/CN=${FQDN}/O=archivmail/C=DE" \
|
||||
-addext "subjectAltName=DNS:${FQDN},DNS:$(hostname -s),IP:${SERVER_IP}" \
|
||||
2>/dev/null
|
||||
chmod 640 "$SSL_DIR/archivmail.key"
|
||||
chmod 644 "$SSL_DIR/archivmail.crt"
|
||||
chown "root:$AM_USER" "$SSL_DIR/archivmail.key"
|
||||
log "TLS-Zertifikat erstellt: $SSL_DIR/archivmail.crt (FQDN: $FQDN, IP: $SERVER_IP)"
|
||||
else
|
||||
log "TLS-Zertifikat existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── 6. PostgreSQL ─────────────────────────────────────────────────────────
|
||||
info "Richte PostgreSQL ein..."
|
||||
systemctl enable postgresql --quiet
|
||||
systemctl start postgresql
|
||||
|
||||
# Falls config.yml schon existiert, DB-Passwort daraus lesen (verhindert Passwort-Mismatch bei Re-Install)
|
||||
if [ -f "$CONFIG_DIR/config.yml" ]; then
|
||||
EXISTING_PW=$(grep -A5 '^database:' "$CONFIG_DIR/config.yml" | awk '/password:/{print $2}' | head -1)
|
||||
[[ -n "$EXISTING_PW" ]] && DB_PASSWORD="$EXISTING_PW" && info "DB-Passwort aus vorhandener config.yml übernommen"
|
||||
fi
|
||||
|
||||
su -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='archivmail'\" | grep -q 1 \
|
||||
&& psql -c \"ALTER USER archivmail WITH PASSWORD '$DB_PASSWORD'\" \
|
||||
|| psql -c \"CREATE USER archivmail WITH PASSWORD '$DB_PASSWORD'\"" postgres
|
||||
su -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='archivmail'\" | grep -q 1 || \
|
||||
psql -c \"CREATE DATABASE archivmail OWNER archivmail\"" postgres
|
||||
su -c "psql archivmail -c \"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO archivmail;\"" postgres
|
||||
su -c "psql archivmail -c \"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO archivmail;\"" postgres
|
||||
su -c "psql archivmail -c \"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO archivmail;\"" postgres
|
||||
su -c "psql archivmail -c \"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO archivmail;\"" postgres
|
||||
log "PostgreSQL eingerichtet"
|
||||
|
||||
# ── 7. Konfiguration ──────────────────────────────────────────────────────
|
||||
info "Erstelle Konfigurationsdatei..."
|
||||
if [ ! -f "$CONFIG_DIR/config.yml" ]; then
|
||||
cat > "$CONFIG_DIR/config.yml" << CONFIG
|
||||
# archivmail Konfiguration – generiert am $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
server:
|
||||
@@ -175,16 +519,16 @@ imap_server:
|
||||
tls_cert: ${SSL_DIR}/archivmail.crt
|
||||
tls_key: ${SSL_DIR}/archivmail.key
|
||||
CONFIG
|
||||
chmod 640 "$CONFIG_DIR/config.yml"
|
||||
chown "root:$AM_USER" "$CONFIG_DIR/config.yml"
|
||||
log "Konfiguration erstellt: $CONFIG_DIR/config.yml"
|
||||
else
|
||||
log "config.yml existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
chmod 640 "$CONFIG_DIR/config.yml"
|
||||
chown "root:$AM_USER" "$CONFIG_DIR/config.yml"
|
||||
log "Konfiguration erstellt: $CONFIG_DIR/config.yml"
|
||||
else
|
||||
log "config.yml existiert bereits – wird nicht überschrieben"
|
||||
fi
|
||||
|
||||
# ── 8. Nginx (HTTP + HTTPS) ────────────────────────────────────────────────────
|
||||
info "Konfiguriere Nginx (HTTP → HTTPS Redirect + TLS)..."
|
||||
cat > /etc/nginx/sites-available/archivmail << NGINX
|
||||
# ── 8. Nginx ──────────────────────────────────────────────────────────────
|
||||
info "Konfiguriere nginx (HTTP → HTTPS + TLS)..."
|
||||
cat > /etc/nginx/sites-available/archivmail << NGINX
|
||||
# HTTP → HTTPS Redirect
|
||||
server {
|
||||
listen 80;
|
||||
@@ -236,15 +580,15 @@ server {
|
||||
error_log /var/log/nginx/archivmail.error.log;
|
||||
}
|
||||
NGINX
|
||||
ln -sf /etc/nginx/sites-available/archivmail /etc/nginx/sites-enabled/archivmail
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t
|
||||
systemctl enable nginx --quiet
|
||||
systemctl restart nginx
|
||||
log "Nginx konfiguriert (HTTP→HTTPS, TLS)"
|
||||
ln -sf /etc/nginx/sites-available/archivmail /etc/nginx/sites-enabled/archivmail
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t
|
||||
systemctl enable nginx --quiet
|
||||
systemctl restart nginx
|
||||
log "nginx konfiguriert"
|
||||
|
||||
# ── 9. logrotate ──────────────────────────────────────────────────────────────
|
||||
cat > /etc/logrotate.d/archivmail << LOGROTATE
|
||||
# ── 9. logrotate ──────────────────────────────────────────────────────────
|
||||
cat > /etc/logrotate.d/archivmail << LOGROTATE
|
||||
${LOG_DIR}/audit.log {
|
||||
daily
|
||||
rotate 365
|
||||
@@ -255,11 +599,11 @@ ${LOG_DIR}/audit.log {
|
||||
create 640 ${AM_USER} ${AM_USER}
|
||||
}
|
||||
LOGROTATE
|
||||
log "logrotate konfiguriert"
|
||||
log "logrotate konfiguriert"
|
||||
|
||||
# ── 10. systemd Units ─────────────────────────────────────────────────────────
|
||||
info "Erstelle systemd Units..."
|
||||
cat > /etc/systemd/system/archivmail.service << UNIT
|
||||
# ── 10. systemd Units ─────────────────────────────────────────────────────
|
||||
info "Erstelle systemd Units..."
|
||||
cat > /etc/systemd/system/archivmail.service << UNIT
|
||||
[Unit]
|
||||
Description=archivmail Mail Archive Daemon
|
||||
After=network.target postgresql.service
|
||||
@@ -286,7 +630,7 @@ ReadOnlyPaths=${CONFIG_DIR} ${SSL_DIR}
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
cat > /etc/systemd/system/archivmail-web.service << UNIT
|
||||
cat > /etc/systemd/system/archivmail-web.service << UNIT
|
||||
[Unit]
|
||||
Description=archivmail Web Frontend
|
||||
After=network.target archivmail.service
|
||||
@@ -310,134 +654,108 @@ SyslogIdentifier=archivmail-web
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable archivmail archivmail-web --quiet
|
||||
log "systemd Units erstellt und aktiviert"
|
||||
systemctl daemon-reload
|
||||
systemctl enable archivmail archivmail-web --quiet
|
||||
log "systemd Units erstellt und aktiviert"
|
||||
|
||||
# ── 11. update.sh installieren und erstes Deployment ──────────────────────────
|
||||
info "Installiere update.sh und führe erstes Deployment durch..."
|
||||
curl -fsSL "${REPO_URL/\.git/}/raw/branch/main/update.sh" -o "$INSTALL_DIR/update.sh" 2>/dev/null \
|
||||
|| { warn "update.sh konnte nicht von Gitea geladen werden – überspringe Deployment"; }
|
||||
# ── 11. Erstes Deployment via update.sh ───────────────────────────────────
|
||||
info "Installiere update.sh und führe erstes Deployment durch..."
|
||||
_update_url="${REPO_URL/\.git/}/raw/branch/main/update.sh"
|
||||
# GitHub-URLs anpassen (raw.githubusercontent.com statt github.com/raw/...)
|
||||
if [[ "$REPO_URL" == *"github.com"* ]]; then
|
||||
_repo_path="${REPO_URL#*github.com/}"
|
||||
_repo_path="${_repo_path%.git}"
|
||||
_update_url="https://raw.githubusercontent.com/${_repo_path}/main/update.sh"
|
||||
fi
|
||||
|
||||
if [ -f "$INSTALL_DIR/update.sh" ]; then
|
||||
chmod +x "$INSTALL_DIR/update.sh"
|
||||
log "update.sh installiert: $INSTALL_DIR/update.sh"
|
||||
info "Führe erstes Deployment durch (Build + Start)..."
|
||||
bash "$INSTALL_DIR/update.sh"
|
||||
# Echte Passwörter aus Journal lesen (Backend gibt sie beim ersten Start aus)
|
||||
# Auf Backend warten (bis zu 15 Sekunden)
|
||||
for _i in $(seq 1 15); do
|
||||
_pw=$(journalctl -u archivmail --no-pager -n 100 | grep 'admin' | grep -oP ':\s+\K[0-9a-f]{16,}' | tail -1)
|
||||
[[ -n "$_pw" ]] && break
|
||||
sleep 1
|
||||
done
|
||||
PW_SUPERADMIN=$(journalctl -u archivmail --no-pager -n 100 | grep 'superadmin' | grep -oP ':\s+\K\S+' | tail -1)
|
||||
PW_ADMIN=$(journalctl -u archivmail --no-pager -n 100 | grep ' admin ' | grep -v superadmin | grep -oP ':\s+\K\S+' | tail -1)
|
||||
PW_AUDITOR=$(journalctl -u archivmail --no-pager -n 100 | grep 'auditor' | grep -oP ':\s+\K\S+' | tail -1)
|
||||
[[ -n "$PW_ADMIN" ]] || PW_ADMIN="(nicht gefunden — siehe: journalctl -u archivmail | grep admin)"
|
||||
[[ -n "$PW_AUDITOR" ]] || PW_AUDITOR="(nicht gefunden — siehe: journalctl -u archivmail | grep auditor)"
|
||||
[[ -n "$PW_SUPERADMIN" ]] || PW_SUPERADMIN="(nicht gefunden — siehe: journalctl -u archivmail | grep superadmin)"
|
||||
else
|
||||
warn "update.sh fehlt — manuell ausführen: bash $INSTALL_DIR/update.sh"
|
||||
PW_SUPERADMIN="(noch nicht generiert)"
|
||||
PW_ADMIN="(noch nicht generiert)"
|
||||
PW_AUDITOR="(noch nicht generiert)"
|
||||
fi
|
||||
curl -fsSL "$_update_url" -o "$INSTALL_DIR/update.sh" 2>/dev/null \
|
||||
|| { warn "update.sh konnte nicht geladen werden – überspringe Deployment"; }
|
||||
|
||||
# ── Zusammenfassung in Datei speichern ────────────────────────────────────────
|
||||
SUMMARY_FILE="$CONFIG_DIR/install-summary.txt"
|
||||
cat > "$SUMMARY_FILE" << SUMMARY
|
||||
archivmail Installation — $(date '+%d.%m.%Y %H:%M:%S')
|
||||
if [ -f "$INSTALL_DIR/update.sh" ]; then
|
||||
chmod +x "$INSTALL_DIR/update.sh"
|
||||
log "update.sh installiert"
|
||||
info "Führe erstes Deployment durch..."
|
||||
bash "$INSTALL_DIR/update.sh"
|
||||
for _i in $(seq 1 15); do
|
||||
_pw=$(journalctl -u archivmail --no-pager -n 100 | grep 'admin' | grep -oP ':\s+\K[0-9a-f]{16,}' | tail -1)
|
||||
[[ -n "$_pw" ]] && break
|
||||
sleep 1
|
||||
done
|
||||
PW_SUPERADMIN=$(journalctl -u archivmail --no-pager -n 100 | grep 'superadmin' | grep -oP ':\s+\K\S+' | tail -1)
|
||||
PW_ADMIN=$(journalctl -u archivmail --no-pager -n 100 | grep ' admin ' | grep -v superadmin | grep -oP ':\s+\K\S+' | tail -1)
|
||||
PW_AUDITOR=$(journalctl -u archivmail --no-pager -n 100 | grep 'auditor' | grep -oP ':\s+\K\S+' | tail -1)
|
||||
[[ -n "$PW_ADMIN" ]] || PW_ADMIN="(nicht gefunden — journalctl -u archivmail | grep admin)"
|
||||
[[ -n "$PW_AUDITOR" ]] || PW_AUDITOR="(nicht gefunden — journalctl -u archivmail | grep auditor)"
|
||||
[[ -n "$PW_SUPERADMIN" ]] || PW_SUPERADMIN="(nicht gefunden — journalctl -u archivmail | grep superadmin)"
|
||||
else
|
||||
warn "update.sh fehlt — manuell: bash $INSTALL_DIR/update.sh"
|
||||
PW_SUPERADMIN="(noch nicht generiert)"; PW_ADMIN="(noch nicht generiert)"; PW_AUDITOR="(noch nicht generiert)"
|
||||
fi
|
||||
|
||||
# ── Zusammenfassung ───────────────────────────────────────────────────────
|
||||
SUMMARY_FILE="$CONFIG_DIR/install-summary.txt"
|
||||
cat > "$SUMMARY_FILE" << SUMMARY
|
||||
archivmail Native-Installation — $(date '+%d.%m.%Y %H:%M:%S')
|
||||
Server: $FQDN
|
||||
|
||||
=== ANGELEGTE BENUTZER & PASSWÖRTER ===
|
||||
=== ZUGANGSDATEN ===
|
||||
|
||||
Systembenutzer (Linux):
|
||||
Benutzer: $AM_USER
|
||||
Shell: /bin/false (kein Login)
|
||||
Home: $STORE_DIR
|
||||
Datenbank: archivmail / $DB_PASSWORD
|
||||
API-Secret: $API_SECRET
|
||||
|
||||
Datenbank (PostgreSQL):
|
||||
Datenbank: archivmail
|
||||
Benutzer: archivmail
|
||||
Passwort: $DB_PASSWORD
|
||||
Verbindung: 127.0.0.1:5432
|
||||
|
||||
API-Secret (JWT + AES-Schlüsselableitung):
|
||||
Secret: $API_SECRET
|
||||
|
||||
Web-Anwendung (UNBEDINGT ÄNDERN!):
|
||||
Superadmin: superadmin@archivmail / $PW_SUPERADMIN
|
||||
Admin: admin@archivmail / $PW_ADMIN
|
||||
Auditor: auditor@archivmail / $PW_AUDITOR
|
||||
Web-Logins (UNBEDINGT ÄNDERN!):
|
||||
superadmin@archivmail / $PW_SUPERADMIN
|
||||
admin@archivmail / $PW_ADMIN
|
||||
auditor@archivmail / $PW_AUDITOR
|
||||
|
||||
=== DIENSTE ===
|
||||
|
||||
Web (HTTPS): https://$FQDN
|
||||
IMAP (TLS): $FQDN:993
|
||||
SMTP: $FQDN:2525
|
||||
Web (HTTPS): https://$FQDN
|
||||
IMAP (TLS): $FQDN:993
|
||||
SMTP: $FQDN:2525
|
||||
|
||||
=== DATEIPFADE ===
|
||||
|
||||
Konfiguration: $CONFIG_DIR/config.yml
|
||||
Keyfile: $CONFIG_DIR/keyfile
|
||||
TLS-Zertifikat: $SSL_DIR/archivmail.crt
|
||||
TLS-Schlüssel: $SSL_DIR/archivmail.key
|
||||
Mail-Speicher: $STORE_DIR/
|
||||
Logs: $LOG_DIR/
|
||||
Updater: $INSTALL_DIR/update.sh
|
||||
|
||||
=== HINWEISE ===
|
||||
|
||||
- Das TLS-Zertifikat ist selbstsigniert (10 Jahre gültig).
|
||||
Im Browser: Ausnahme hinzufügen oder Zertifikat importieren.
|
||||
Für vertrauenswürdiges Zertifikat: Admin → Zertifikat → Let's Encrypt
|
||||
- DB-Passwort und API-Secret stehen in $CONFIG_DIR/config.yml (chmod 640).
|
||||
- Keyfile NIEMALS löschen oder überschreiben — alle Mails werden damit entschlüsselt.
|
||||
- Diese Datei nach dem ersten Login löschen oder sicher aufbewahren!
|
||||
SUMMARY
|
||||
chmod 600 "$SUMMARY_FILE"
|
||||
log "Zusammenfassung gespeichert: $SUMMARY_FILE"
|
||||
chmod 600 "$SUMMARY_FILE"
|
||||
log "Zusammenfassung: $SUMMARY_FILE"
|
||||
|
||||
# ── Abschlussbericht ──────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo " ╔══════════════════════════════════════════════════════════╗"
|
||||
echo " ║ Installation abgeschlossen! ║"
|
||||
echo " ╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " Hostname (FQDN): $FQDN"
|
||||
echo ""
|
||||
echo " Pfade:"
|
||||
echo " Binaries: $INSTALL_DIR/"
|
||||
echo " Mail-Speicher: $STORE_DIR/"
|
||||
echo " Konfiguration: $CONFIG_DIR/config.yml"
|
||||
echo " Keyfile: $CONFIG_DIR/keyfile (chmod 400 – sicher aufbewahren!)"
|
||||
echo " TLS-Zertifikat: $SSL_DIR/archivmail.crt"
|
||||
echo " Logs: $LOG_DIR/"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────┐"
|
||||
echo " │ ANGELEGTE BENUTZER & PASSWÖRTER │"
|
||||
echo " ├─────────────────────────────────────────────────────────┤"
|
||||
printf " │ DB archivmail: %-38s │\n" "$DB_PASSWORD"
|
||||
echo " ├─────────────────────────────────────────────────────────┤"
|
||||
echo " │ Web-Logins (UNBEDINGT ÄNDERN!): │"
|
||||
printf " │ superadmin / %-38s│\n" "$PW_SUPERADMIN"
|
||||
printf " │ admin / %-38s│\n" "$PW_ADMIN"
|
||||
printf " │ auditor / %-38s│\n" "$PW_AUDITOR"
|
||||
echo " ├─────────────────────────────────────────────────────────┤"
|
||||
printf " │ API-Secret: %-38s │\n" "${API_SECRET:0:38}"
|
||||
echo " └─────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " Vollständige Zusammenfassung: $SUMMARY_FILE"
|
||||
echo ""
|
||||
echo " Dienste:"
|
||||
echo " Web (HTTPS): https://$FQDN"
|
||||
echo " IMAP (TLS): $FQDN:993"
|
||||
echo " SMTP: $FQDN:2525"
|
||||
echo ""
|
||||
echo " Hinweis: Das TLS-Zertifikat ist selbstsigniert."
|
||||
echo " Für ein vertrauenswürdiges Zertifikat: Admin → Zertifikat → Let's Encrypt"
|
||||
echo ""
|
||||
warn "Zusammenfassung mit Passwörtern: $SUMMARY_FILE (chmod 600)"
|
||||
warn "Standardpasswörter unbedingt nach dem ersten Login ändern!"
|
||||
echo ""
|
||||
# ── Abschluss ─────────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo " ╔══════════════════════════════════════════════════════════╗"
|
||||
echo " ║ Installation abgeschlossen! ║"
|
||||
echo " ╚══════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo " Web (HTTPS): https://$FQDN"
|
||||
echo " IMAP (TLS): $FQDN:993"
|
||||
echo " SMTP: $FQDN:2525"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────┐"
|
||||
echo " │ ANGELEGTE BENUTZER & PASSWÖRTER │"
|
||||
echo " ├─────────────────────────────────────────────────────────┤"
|
||||
printf " │ DB archivmail: %-38s │\n" "$DB_PASSWORD"
|
||||
echo " ├─────────────────────────────────────────────────────────┤"
|
||||
echo " │ Web-Logins (UNBEDINGT ÄNDERN!): │"
|
||||
printf " │ superadmin / %-38s│\n" "$PW_SUPERADMIN"
|
||||
printf " │ admin / %-38s│\n" "$PW_ADMIN"
|
||||
printf " │ auditor / %-38s│\n" "$PW_AUDITOR"
|
||||
echo " └─────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
warn "Zusammenfassung mit Passwörtern: $SUMMARY_FILE"
|
||||
warn "Standardpasswörter unbedingt nach dem ersten Login ändern!"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# MODUS AUSFÜHREN
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
case "$INSTALL_MODE" in
|
||||
docker) install_docker ;;
|
||||
native) install_native ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user