#!/bin/bash # ═══════════════════════════════════════════════════════════════════════════════ # Network-MGMT — Deployment Script # # Auf dem LOKALEN Rechner ausführen: bash deploy.sh # # Voraussetzungen lokal: ssh, scp, tar # Voraussetzungen Server: curl, systemd (Docker wird automatisch installiert) # ═══════════════════════════════════════════════════════════════════════════════ set -euo pipefail # ── Farben ───────────────────────────────────────────────────────────────────── R='\033[0;31m'; G='\033[0;32m'; Y='\033[1;33m'; B='\033[0;34m' BOLD='\033[1m'; NC='\033[0m' # ── Banner ────────────────────────────────────────────────────────────────────── echo "" echo -e "${B}${BOLD} ╔══════════════════════════════════════════════╗${NC}" echo -e "${B}${BOLD} ║ Network-MGMT — Deployment Script ║${NC}" echo -e "${B}${BOLD} ╚══════════════════════════════════════════════╝${NC}" echo "" # ── Eingaben ─────────────────────────────────────────────────────────────────── echo -e "${BOLD}1/3 Server-Verbindung${NC}" read -rp " Server-IP / Hostname : " SERVER_HOST read -rp " SSH-Benutzer [root] : " SERVER_USER SERVER_USER="${SERVER_USER:-root}" read -rp " SSH-Port [22] : " SERVER_PORT SERVER_PORT="${SERVER_PORT:-22}" read -rp " Ziel-Pfad [/opt/network-mgmt] : " DEPLOY_PATH DEPLOY_PATH="${DEPLOY_PATH:-/opt/network-mgmt}" echo "" echo -e "${BOLD}2/3 App-Konfiguration${NC}" read -rp " App-URL (z.B. http://${SERVER_HOST}:8080) : " APP_URL APP_URL="${APP_URL:-http://${SERVER_HOST}:8080}" read -rp " App-Port [8080] : " APP_PORT APP_PORT="${APP_PORT:-8080}" echo "" echo -e "${BOLD}3/3 Datenbank${NC}" read -rsp " DB-Passwort (User) : " DB_PASSWORD; echo read -rsp " DB-Root-Passwort : " DB_ROOT_PASSWORD; echo echo "" echo -e "${BOLD}Optional: Gitea (Update-Funktion — jederzeit in .env nachträglich eintragbar)${NC}" read -rp " Gitea-URL [leer lassen] : " GITEA_URL GITEA_URL="${GITEA_URL:-}" # ── Zusammenfassung + Bestätigung ────────────────────────────────────────────── echo "" echo -e "${Y}─── Zusammenfassung ─────────────────────────────────────${NC}" echo " Server : ${SERVER_USER}@${SERVER_HOST}:${SERVER_PORT}" echo " Pfad : ${DEPLOY_PATH}" echo " URL : ${APP_URL}" echo " Port : ${APP_PORT}" echo -e "${Y}─────────────────────────────────────────────────────────${NC}" echo "" read -rp "Deployment jetzt starten? [j/N] " CONFIRM [[ "${CONFIRM,,}" == "j" ]] || { echo "Abgebrochen."; exit 0; } SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ARCHIVE="/tmp/network-mgmt-$(date +%Y%m%d_%H%M%S).tar.gz" REMOTE_SCRIPT="/tmp/nm_setup_$$.sh" # ── App verpacken ────────────────────────────────────────────────────────────── echo "" echo -e "${Y}▶ App wird gepackt ...${NC}" tar -czf "$ARCHIVE" \ --exclude='.git' \ --exclude='vendor' \ --exclude='node_modules' \ --exclude='.env' \ --exclude='storage/logs' \ --exclude='storage/framework/cache' \ --exclude='storage/framework/sessions' \ --exclude='storage/framework/views' \ --exclude='bootstrap/cache' \ --exclude='deploy.sh' \ -C "$SCRIPT_DIR" . echo -e "${G} ✓ Archiv: $(du -sh "$ARCHIVE" | cut -f1)${NC}" # ── Server-Setup-Skript erzeugen ─────────────────────────────────────────────── # Variablen werden hier lokal eingebettet → kein SSH-Quoting-Problem { printf '#!/bin/bash\nset -euo pipefail\n' printf 'G='"'"'\033[0;32m'"'"'; Y='"'"'\033[1;33m'"'"'; BOLD='"'"'\033[1m'"'"'; NC='"'"'\033[0m'"'"'\n' printf 'DEPLOY_PATH=%q\n' "$DEPLOY_PATH" printf 'APP_URL=%q\n' "$APP_URL" printf 'APP_PORT=%q\n' "$APP_PORT" printf 'DB_PASSWORD=%q\n' "$DB_PASSWORD" printf 'DB_ROOT_PASSWORD=%q\n' "$DB_ROOT_PASSWORD" printf 'GITEA_URL=%q\n' "$GITEA_URL" cat << 'REMOTE_BODY' echo "" echo -e "${Y}▶ Docker prüfen / installieren ...${NC}" if ! command -v docker &>/dev/null; then curl -fsSL https://get.docker.com | sh systemctl enable --now docker echo -e "${G} ✓ Docker installiert: $(docker --version | awk '{print $3}' | tr -d ',')${NC}" else echo -e "${G} ✓ Docker: $(docker --version | awk '{print $3}' | tr -d ',')${NC}" fi # Docker Compose Plugin if ! docker compose version &>/dev/null 2>&1; then echo -e "${Y} Docker Compose Plugin wird installiert ...${NC}" mkdir -p "${HOME}/.docker/cli-plugins" ARCH="$(uname -m)" curl -fsSL \ "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-${ARCH}" \ -o "${HOME}/.docker/cli-plugins/docker-compose" chmod +x "${HOME}/.docker/cli-plugins/docker-compose" fi echo -e "${G} ✓ Docker Compose: $(docker compose version --short 2>/dev/null || echo 'ok')${NC}" # App-Verzeichnis vorbereiten echo "" echo -e "${Y}▶ App entpacken nach ${DEPLOY_PATH} ...${NC}" mkdir -p "$DEPLOY_PATH" # Bestehende .env sichern ENV_BACKUP="" if [ -f "${DEPLOY_PATH}/.env" ]; then ENV_BACKUP="$(cat "${DEPLOY_PATH}/.env")" echo -e "${G} ✓ Bestehende .env gesichert${NC}" fi # Entpacken tar -xzf /tmp/network-mgmt.tar.gz -C "$DEPLOY_PATH" rm -f /tmp/network-mgmt.tar.gz cd "$DEPLOY_PATH" # Storage-Verzeichnisse sicherstellen mkdir -p storage/logs \ storage/framework/cache \ storage/framework/sessions \ storage/framework/views \ bootstrap/cache chmod -R 775 storage bootstrap/cache # .env konfigurieren if [ -n "$ENV_BACKUP" ]; then echo "$ENV_BACKUP" > .env echo -e "${G} ✓ Bestehende .env wiederhergestellt${NC}" else cp .env.example .env sed -i "s|APP_URL=.*|APP_URL=${APP_URL}|" .env sed -i "s|APP_PORT=.*|APP_PORT=${APP_PORT}|" .env sed -i "s|DB_PASSWORD=secret|DB_PASSWORD=${DB_PASSWORD}|" .env sed -i "s|DB_ROOT_PASSWORD=rootsecret|DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}|" .env if [ -n "${GITEA_URL}" ]; then sed -i "s|GITEA_URL=.*|GITEA_URL=${GITEA_URL}|" .env fi echo -e "${G} ✓ .env konfiguriert${NC}" fi # Container bauen und starten echo "" echo -e "${Y}▶ Docker-Image bauen und starten (beim ersten Mal 3–5 Minuten) ...${NC}" docker compose up -d --build # Warten bis App bereit echo -e "${Y} Warte auf Container ...${NC}" sleep 5 for i in $(seq 1 20); do if docker compose ps | grep -qE "healthy|Up"; then break fi sleep 5 done # Abschluss echo "" docker compose ps echo "" echo -e "${G}${BOLD}╔══════════════════════════════════════════════════════╗${NC}" echo -e "${G}${BOLD}║ ✓ Network-MGMT erfolgreich installiert! ║${NC}" echo -e "${G}${BOLD}║ ║${NC}" printf "${G}${BOLD}║ URL: %-44s║${NC}\n" "${APP_URL}" printf "${G}${BOLD}║ Pfad: %-44s║${NC}\n" "${DEPLOY_PATH}" echo -e "${G}${BOLD}║ ║${NC}" echo -e "${G}${BOLD}║ Logs: docker compose logs -f (im App-Pfad) ║${NC}" echo -e "${G}${BOLD}║ Stop: docker compose down ║${NC}" echo -e "${G}${BOLD}╚══════════════════════════════════════════════════════╝${NC}" echo "" REMOTE_BODY } > "$REMOTE_SCRIPT" chmod +x "$REMOTE_SCRIPT" # ── Dateien auf Server übertragen ────────────────────────────────────────────── echo "" echo -e "${Y}▶ Übertrage auf ${SERVER_USER}@${SERVER_HOST} ...${NC}" ssh -p "$SERVER_PORT" "${SERVER_USER}@${SERVER_HOST}" "mkdir -p '${DEPLOY_PATH}'" scp -q -P "$SERVER_PORT" "$ARCHIVE" "${SERVER_USER}@${SERVER_HOST}:/tmp/network-mgmt.tar.gz" scp -q -P "$SERVER_PORT" "$REMOTE_SCRIPT" "${SERVER_USER}@${SERVER_HOST}:/tmp/nm_setup.sh" echo -e "${G} ✓ Übertragen${NC}" # Lokal aufräumen rm -f "$ARCHIVE" "$REMOTE_SCRIPT" # ── Remote-Setup ausführen ───────────────────────────────────────────────────── echo "" echo -e "${Y}▶ Server-Setup läuft ...${NC}" echo -e "${Y}─────────────────────────────────────────────${NC}" ssh -p "$SERVER_PORT" "${SERVER_USER}@${SERVER_HOST}" "bash /tmp/nm_setup.sh; rm -f /tmp/nm_setup.sh" echo -e "${Y}─────────────────────────────────────────────${NC}" echo "" echo -e "${G}${BOLD}✓ Deployment abgeschlossen! → ${APP_URL}${NC}" echo ""