From 3dc9c2c42d5f4e9def360edb75a822d9f178ff52 Mon Sep 17 00:00:00 2001 From: Andreas Rudolph Date: Fri, 3 Jul 2026 01:04:24 +0200 Subject: [PATCH] v0.10.0: deploy.sh via Gitea --- deploy.sh | 265 ++++++++++++++++++++++-------------------------------- 1 file changed, 109 insertions(+), 156 deletions(-) diff --git a/deploy.sh b/deploy.sh index 39857ef..ec260b7 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,214 +1,167 @@ #!/bin/bash -# ═══════════════════════════════════════════════════════════════════════════════ -# Network-MGMT — Deployment Script +# ═══════════════════════════════════════════════════════════════════ +# Network-MGMT — Deploy-Skript # -# Auf dem LOKALEN Rechner ausführen: bash deploy.sh +# Ausführen auf deinem lokalen Rechner: bash deploy.sh +# Der Zielserver klont die App direkt von Gitea. # -# Voraussetzungen lokal: ssh, scp, tar -# Voraussetzungen Server: curl, systemd (Docker wird automatisch installiert) -# ═══════════════════════════════════════════════════════════════════════════════ +# Voraussetzung: SSH-Zugang zum Zielserver +# ═══════════════════════════════════════════════════════════════════ 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}" +G='\033[0;32m'; Y='\033[1;33m'; B='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m' 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 -e "${B}${BOLD}╔═══════════════════════════════════════════╗${NC}" +echo -e "${B}${BOLD}║ Network-MGMT — Deployment ║${NC}" +echo -e "${B}${BOLD}╚═══════════════════════════════════════════╝${NC}" +echo "" + +# ── Eingaben ─────────────────────────────────────────────────────── +echo -e "${BOLD}Kunden-Server (Ziel)${NC}" +read -rp " IP-Adresse / 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}" 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 -e "${BOLD}Gitea${NC}" +read -rp " Gitea-URL (dein Server) : " GITEA_URL; GITEA_URL="${GITEA_URL:-https://git.mms-systemservice.de}" +read -rp " Gitea-Benutzer : " GITEA_USER; GITEA_USER="${GITEA_USER:-gitea-mms}" +read -rsp " Gitea-Passwort : " GITEA_PASS; 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:-}" +echo -e "${BOLD}App-Einstellungen${NC}" +read -rp " App-Port [8080] : " APP_PORT; APP_PORT="${APP_PORT:-8080}" +APP_URL="http://${SERVER_HOST}:${APP_PORT}" +echo -e " → Erreichbar unter: ${G}${APP_URL}${NC}" -# ── 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 -e "${BOLD}Datenbank${NC}" +read -rsp " DB-Passwort : " DB_PASSWORD; echo +DB_ROOT_PASSWORD="${DB_PASSWORD}ROOT" + +# ── Bestätigung ──────────────────────────────────────────────────── echo "" -read -rp "Deployment jetzt starten? [j/N] " CONFIRM +echo -e "${Y}────────────────────────────────────────────────${NC}" +echo " Ziel: ${SERVER_USER}@${SERVER_HOST}:${SERVER_PORT}" +echo " Quelle: ${GITEA_URL}/${GITEA_USER}/Network-MGMT" +echo " App-URL: ${APP_URL}" +echo -e "${Y}────────────────────────────────────────────────${NC}" +echo "" +read -rp "Deployment 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 +# ── Setup-Skript mit eingebetteten Werten erzeugen ───────────────── +REMOTE_SCRIPT="/tmp/nm_deploy_$$.sh" { -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' +printf '#!/bin/bash\nset -euo pipefail\n\n' +printf 'G='"'"'\033[0;32m'"'"'; Y='"'"'\033[1;33m'"'"'; BOLD='"'"'\033[1m'"'"'; NC='"'"'\033[0m'"'"'\n\n' +printf 'GITEA_URL=%q\n' "$GITEA_URL" +printf 'GITEA_USER=%q\n' "$GITEA_USER" +printf 'GITEA_PASS=%q\n' "$GITEA_PASS" +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_FULL_URL=%q\n' "${GITEA_URL}" +cat << 'SETUP' + +DEPLOY_PATH="/opt/network-mgmt" +REPO_URL="${GITEA_URL/https:\/\//https://${GITEA_USER}:${GITEA_PASS}@}" +REPO_URL="${REPO_URL}/gitea-mms/Network-MGMT.git" +# Credentials in URL einbauen +CLONE_URL=$(echo "$GITEA_URL" | sed "s|https://|https://${GITEA_USER}:${GITEA_PASS}@|") +CLONE_URL="${CLONE_URL}/${GITEA_USER}/Network-MGMT.git" echo "" -echo -e "${Y}▶ Docker prüfen / installieren ...${NC}" +echo -e "${Y}[1/4] 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 +echo -e "${G} ✓ Docker: $(docker --version | awk '{print $3}' | tr -d ',')${NC}" -# 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)" + mkdir -p "${HOME}/.docker/cli-plugins" curl -fsSL \ - "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-${ARCH}" \ - -o "${HOME}/.docker/cli-plugins/docker-compose" + "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}" +echo -e "${G} ✓ Docker Compose: $(docker compose version --short 2>/dev/null)${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}" +echo -e "${Y}[2/4] Repository von Gitea klonen / aktualisieren ...${NC}" +if [ -d "${DEPLOY_PATH}/.git" ]; then + cd "$DEPLOY_PATH" + git pull + echo -e "${G} ✓ Repository aktualisiert${NC}" +else + git clone "$CLONE_URL" "$DEPLOY_PATH" + echo -e "${G} ✓ Repository geklont${NC}" fi -# Entpacken -tar -xzf /tmp/network-mgmt.tar.gz -C "$DEPLOY_PATH" -rm -f /tmp/network-mgmt.tar.gz +echo "" +echo -e "${Y}[3/4] Konfiguration ...${NC}" cd "$DEPLOY_PATH" -# Storage-Verzeichnisse sicherstellen -mkdir -p storage/logs \ - storage/framework/cache \ - storage/framework/sessions \ - storage/framework/views \ - bootstrap/cache +mkdir -p storage/logs storage/framework/{cache,sessions,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 +if [ ! -f ".env" ]; then 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}" + 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 + sed -i "s|GITEA_URL=.*|GITEA_URL=${GITEA_FULL_URL}|" .env + sed -i "s|GITEA_REPO=.*|GITEA_REPO=${GITEA_USER}/Network-MGMT|" .env + echo -e "${G} ✓ .env erstellt${NC}" +else + echo -e "${G} ✓ .env bereits vorhanden (nicht überschrieben)${NC}" fi -# Container bauen und starten echo "" -echo -e "${Y}▶ Docker-Image bauen und starten (beim ersten Mal 3–5 Minuten) ...${NC}" +echo -e "${Y}[4/4] Container bauen und starten ...${NC}" +echo " (Erster Start: 3–5 Minuten)" docker compose up -d --build -# Warten bis App bereit -echo -e "${Y} Warte auf Container ...${NC}" -sleep 5 +echo " Warte auf Start ..." +sleep 8 for i in $(seq 1 20); do - if docker compose ps | grep -qE "healthy|Up"; then - break - fi - sleep 5 + docker compose ps | grep -qE "healthy|Up" && break || 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 -e "${G}${BOLD}╔══════════════════════════════════════════════════╗${NC}" +echo -e "${G}${BOLD}║ ✓ Network-MGMT erfolgreich installiert! ║${NC}" +echo -e "${G}${BOLD}║ ║${NC}" +printf "${G}${BOLD}║ Browser: %-40s║${NC}\n" "${APP_URL}" +printf "${G}${BOLD}║ Pfad: %-40s║${NC}\n" "${DEPLOY_PATH}" +echo -e "${G}${BOLD}║ ║${NC}" +echo -e "${G}${BOLD}║ Logs: docker compose logs -f ║${NC}" +echo -e "${G}${BOLD}║ Stop: docker compose down ║${NC}" +echo -e "${G}${BOLD}╚══════════════════════════════════════════════════╝${NC}" echo "" -REMOTE_BODY +SETUP } > "$REMOTE_SCRIPT" - chmod +x "$REMOTE_SCRIPT" -# ── Dateien auf Server übertragen ────────────────────────────────────────────── +# ── Script auf Server übertragen und ausführen ───────────────────── 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}" +echo -e "${Y}▶ Verbinde mit ${SERVER_USER}@${SERVER_HOST} ...${NC}" +scp -q -P "$SERVER_PORT" "$REMOTE_SCRIPT" "${SERVER_USER}@${SERVER_HOST}:/tmp/nm_deploy.sh" +rm -f "$REMOTE_SCRIPT" -# 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 -e "${Y}▶ Setup läuft (Ausgabe vom Server):${NC}" +echo -e "${Y}────────────────────────────────────────────────${NC}" +ssh -p "$SERVER_PORT" "${SERVER_USER}@${SERVER_HOST}" \ + "bash /tmp/nm_deploy.sh; rm -f /tmp/nm_deploy.sh" +echo -e "${Y}────────────────────────────────────────────────${NC}" echo "" -echo -e "${G}${BOLD}✓ Deployment abgeschlossen! → ${APP_URL}${NC}" +echo -e "${G}${BOLD}✓ Fertig! → ${APP_URL}${NC}" echo ""