initial commit
This commit is contained in:
commit
adcaceb7ac
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Nutzung: $0 <DATEI> (docker-compose.yml|nginx.conf)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DATEI="$1"
|
||||
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="/home/thomas/backup_images/${TIMESTAMP}_config_${DATEI}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
if [ "$DATEI" = "docker-compose.yml" ]; then
|
||||
SRC="/home/thomas/docker-compose.yml"
|
||||
elif [ "$DATEI" = "nginx.conf" ]; then
|
||||
SRC="/home/thomas/container/nginx/nginx.conf"
|
||||
else
|
||||
echo "Unbekannte Datei: $DATEI"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$SRC" "$BACKUP_DIR/"
|
||||
echo "Config-Backup für $DATEI gespeichert unter $BACKUP_DIR/"
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Nutzung: $0 <CONTAINERNAME>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONTAINER="$1"
|
||||
DB_UEBERSICHT="/home/thomas/db_uebersicht.md"
|
||||
read USER PASS < <(tail -n +5 "$DB_UEBERSICHT" | grep "| $CONTAINER " | awk -F '|' '{print $5, $6}' | xargs)
|
||||
|
||||
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="/home/thomas/backup_images/${TIMESTAMP}_db_${CONTAINER}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
echo "Erstelle Dump für $CONTAINER ($USER)..."
|
||||
docker exec $CONTAINER mysqldump -u $USER -p$PASS --all-databases --single-transaction --quick --lock-tables=false > "$BACKUP_DIR/${CONTAINER}.sql" \
|
||||
&& echo "DB-Backup für $CONTAINER gespeichert unter $BACKUP_DIR/${CONTAINER}.sql" \
|
||||
|| echo "Fehler beim Dump von $CONTAINER"
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Nutzung: $0 <IMAGENAME> (z.B. nginx:latest)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IMAGE="$1"
|
||||
SAFE_IMAGE=$(echo $IMAGE | tr '/:' '_')
|
||||
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="/home/thomas/backup_images/${TIMESTAMP}_image_${SAFE_IMAGE}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
docker save "$IMAGE" | gzip > "$BACKUP_DIR/${SAFE_IMAGE}.tar.gz"
|
||||
echo "Image-Backup für $IMAGE gespeichert unter $BACKUP_DIR/${SAFE_IMAGE}.tar.gz"
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Nutzung: $0 <PROJEKT> (webshop|ssv)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJEKT="$1"
|
||||
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="/home/thomas/backup_images/${TIMESTAMP}_media_${PROJEKT}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
if [ "$PROJEKT" = "webshop" ]; then
|
||||
SRC="/home/thomas/container/webshop/cleanbuild/media"
|
||||
elif [ "$PROJEKT" = "ssv" ]; then
|
||||
SRC="/home/thomas/container/ssv/html/media"
|
||||
else
|
||||
echo "Unbekanntes Projekt: $PROJEKT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar czf "$BACKUP_DIR/${PROJEKT}_media.tar.gz" -C "$SRC" .
|
||||
echo "Media-Backup für $PROJEKT gespeichert unter $BACKUP_DIR/${PROJEKT}_media.tar.gz"
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Nutzung: $0 <PROJEKT> (webshop|ssv)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJEKT="$1"
|
||||
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="/home/thomas/backup_images/${TIMESTAMP}_static_${PROJEKT}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
if [ "$PROJEKT" = "webshop" ]; then
|
||||
SRC="/home/thomas/container/webshop/cleanbuild/staticfiles"
|
||||
elif [ "$PROJEKT" = "ssv" ]; then
|
||||
SRC="/home/thomas/container/ssv/html/staticfiles"
|
||||
else
|
||||
echo "Unbekanntes Projekt: $PROJEKT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar czf "$BACKUP_DIR/${PROJEKT}_staticfiles.tar.gz" -C "$SRC" .
|
||||
echo "Staticfiles-Backup für $PROJEKT gespeichert unter $BACKUP_DIR/${PROJEKT}_staticfiles.tar.gz"
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Nutzung: $0 <BACKUP_TIMESTAMP> <DATEI> (docker-compose.yml|nginx.conf)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/home/thomas/backup_images/$1"
|
||||
DATEI="$2"
|
||||
|
||||
if [ "$DATEI" = "docker-compose.yml" ]; then
|
||||
ZIEL="/home/thomas/docker-compose.yml"
|
||||
elif [ "$DATEI" = "nginx.conf" ]; then
|
||||
ZIEL="/home/thomas/container/nginx/nginx.conf"
|
||||
else
|
||||
echo "Unbekannte Datei: $DATEI"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$BACKUP_DIR/$DATEI" ]; then
|
||||
echo "Backup nicht gefunden: $BACKUP_DIR/$DATEI"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stelle $DATEI wieder her..."
|
||||
cp "$BACKUP_DIR/$DATEI" "$ZIEL"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Nutzung: $0 <BACKUP_TIMESTAMP> <CONTAINERNAME>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/home/thomas/backup_images/$1/db_dumps"
|
||||
DB_UEBERSICHT="/home/thomas/db_uebersicht.md"
|
||||
CONTAINER="$2"
|
||||
|
||||
# Hole User und Passwort aus Übersicht
|
||||
read USER PASS < <(tail -n +5 "$DB_UEBERSICHT" | grep "| $CONTAINER " | awk -F '|' '{print $5, $6}' | xargs)
|
||||
|
||||
DUMP_FILE="$BACKUP_DIR/${CONTAINER}.sql"
|
||||
if [ ! -f "$DUMP_FILE" ]; then
|
||||
echo "Dump nicht gefunden: $DUMP_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Importiere Dump für $CONTAINER ($USER)..."
|
||||
cat "$DUMP_FILE" | docker exec -i $CONTAINER mysql -u $USER -p$PASS || echo "Fehler beim Import in $CONTAINER"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Nutzung: $0 <BACKUP_TIMESTAMP> <IMAGENAME> (z.B. nginx_latest)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/home/thomas/backup_images/$1/images"
|
||||
IMAGE="$2"
|
||||
TARFILE="$BACKUP_DIR/${IMAGE}.tar.gz"
|
||||
|
||||
if [ ! -f "$TARFILE" ]; then
|
||||
echo "Backup nicht gefunden: $TARFILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Importiere Image $IMAGE..."
|
||||
gunzip -c "$TARFILE" | docker load
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Nutzung: $0 <BACKUP_TIMESTAMP> <PROJEKT> (webshop|ssv)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/home/thomas/backup_images/$1/volumes"
|
||||
PROJEKT="$2"
|
||||
|
||||
if [ "$PROJEKT" = "webshop" ]; then
|
||||
TARFILE="$BACKUP_DIR/webshop_media.tar.gz"
|
||||
ZIEL="/home/thomas/container/webshop/cleanbuild"
|
||||
elif [ "$PROJEKT" = "ssv" ]; then
|
||||
TARFILE="$BACKUP_DIR/ssv_media.tar.gz"
|
||||
ZIEL="/home/thomas/container/ssv/html"
|
||||
else
|
||||
echo "Unbekanntes Projekt: $PROJEKT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$TARFILE" ]; then
|
||||
echo "Backup nicht gefunden: $TARFILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stelle Media für $PROJEKT wieder her..."
|
||||
tar xzf "$TARFILE" -C "$ZIEL"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Nutzung: $0 <BACKUP_TIMESTAMP> <PROJEKT> (webshop|ssv)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_DIR="/home/thomas/backup_images/$1/volumes"
|
||||
PROJEKT="$2"
|
||||
|
||||
if [ "$PROJEKT" = "webshop" ]; then
|
||||
TARFILE="$BACKUP_DIR/webshop_staticfiles.tar.gz"
|
||||
ZIEL="/home/thomas/container/webshop/cleanbuild"
|
||||
elif [ "$PROJEKT" = "ssv" ]; then
|
||||
TARFILE="$BACKUP_DIR/ssv_staticfiles.tar.gz"
|
||||
ZIEL="/home/thomas/container/ssv/html"
|
||||
else
|
||||
echo "Unbekanntes Projekt: $PROJEKT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$TARFILE" ]; then
|
||||
echo "Backup nicht gefunden: $TARFILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stelle Staticfiles für $PROJEKT wieder her..."
|
||||
tar xzf "$TARFILE" -C "$ZIEL"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
# Zugangsdaten für WD MyCloud EX2 Ultra NAS
|
||||
user=backup
|
||||
password=backupnuk
|
||||
# Freigabe: //192.168.178.101/Backup
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# Übersicht der Docker- und Gitea-Skripte
|
||||
|
||||
## Hauptskripte
|
||||
- **backup_docker.sh**: Erstellt ein vollständiges Backup aller Docker-Images, Volumes, Media/Staticfiles, Konfigurationsdateien und MariaDB-Dumps. Das Backup wird in einem Zeitstempel-Ordner unter `/home/thomas/backup_images/` abgelegt.
|
||||
- **restore_docker.sh**: Stellt ein Backup aus einem Zeitstempel-Ordner komplett wieder her (Images, Volumes, DB-Dumps, Konfigs).
|
||||
- **restore_menu.sh**: Interaktives Menü für alle Backup- und Restore-Funktionen (siehe unten).
|
||||
|
||||
## Einzelne_Restore_Scripte
|
||||
Alle Einzelskripte für gezielte Sicherung und Wiederherstellung liegen in `/home/thomas/scripte/Einzelne_Restore_Scripte/`:
|
||||
- **backup_db.sh**: Sichert gezielt einen Dump einer einzelnen Datenbank (Container).
|
||||
- **backup_media.sh**: Sichert gezielt die Media-Dateien eines Projekts (webshop|ssv).
|
||||
- **backup_staticfiles.sh**: Sichert gezielt die Staticfiles eines Projekts (webshop|ssv).
|
||||
- **backup_image.sh**: Sichert gezielt ein Docker-Image.
|
||||
- **backup_config.sh**: Sichert gezielt docker-compose.yml oder nginx.conf.
|
||||
- **restore_db.sh**: Stellt gezielt den Dump einer einzelnen Datenbank (Container) wieder her.
|
||||
- **restore_media.sh**: Stellt nur die Media-Dateien eines Projekts (webshop|ssv) wieder her.
|
||||
- **restore_staticfiles.sh**: Stellt nur die Staticfiles eines Projekts (webshop|ssv) wieder her.
|
||||
- **restore_image.sh**: Importiert gezielt ein Docker-Image aus einem Backup.
|
||||
- **restore_config.sh**: Stellt gezielt docker-compose.yml oder nginx.conf wieder her.
|
||||
|
||||
## Wartungsscripte
|
||||
Alle Wartungs- und Hilfsskripte liegen in `/home/thomas/scripte/Wartungsscripte/`:
|
||||
- **docker_cleanup.sh**: Entfernt nicht mehr verwendete Docker-Objekte (Container, Images, Volumes) nach Bestätigung.
|
||||
- **cleanup_old_backups.sh**: Löscht alle Backup-Ordner in `/home/thomas/backup_images/`, die älter als 14 Tage sind.
|
||||
- **db_dump_single.sh**: Erstellt einen SQL-Dump einer einzelnen MariaDB im laufenden Container.
|
||||
- **docker_logs.sh**: Zeigt die letzten 100 Zeilen der Logs eines angegebenen Containers an.
|
||||
- **docker_status.sh**: Zeigt alle laufenden und gestoppten Docker-Container an.
|
||||
|
||||
## Git & Gitea Menü
|
||||
- **git_gitea_menu.sh**: Interaktives Menü für lokale Git-Operationen und Gitea-API-Operationen.
|
||||
- **Funktionen:**
|
||||
- Repository klonen: Klont ein bestehendes Repo von Gitea oder einer anderen Quelle.
|
||||
- Status anzeigen: Zeigt den aktuellen Git-Status im aktuellen Verzeichnis.
|
||||
- Pull: Holt die neuesten Änderungen vom Remote-Repo.
|
||||
- Push: Überträgt lokale Commits ins Remote-Repo.
|
||||
- Branch wechseln: Wechselt oder erstellt einen Branch.
|
||||
- Commit: Fügt Änderungen hinzu und erstellt einen Commit.
|
||||
- Gitea: Repo-Liste anzeigen: Zeigt alle Repos des Users auf Gitea.
|
||||
- Gitea: Neues Repo anlegen: Legt ein neues Repository auf Gitea an (Repo-Name wird validiert, Leerzeichen werden ersetzt).
|
||||
- Gitea: Issue anzeigen: Zeigt ein Issue eines Repos an.
|
||||
- Gitea: Issue erstellen: Erstellt ein neues Issue in einem Repo.
|
||||
- **Folgen der Aktionen:**
|
||||
- Repo anlegen: Das neue Repo erscheint sofort auf Gitea, kann geklont und genutzt werden.
|
||||
- Issue erstellen: Das Issue ist sofort im Gitea-Webinterface sichtbar.
|
||||
- Alle Aktionen sind sofort wirksam und können nicht rückgängig gemacht werden.
|
||||
- Die Validierung verhindert ungültige Repo-Namen und sorgt für Kompatibilität mit Gitea.
|
||||
- Mit "z" kann man jederzeit zurück ins Hauptmenü.
|
||||
|
||||
## Nutzung des Backup & Restore Menüs
|
||||
Starte das Menü mit:
|
||||
```bash
|
||||
/home/thomas/scripte/restore_menu.sh
|
||||
```
|
||||
Dort kannst du alle Backup- und Restore-Funktionen bequem auswählen und ausführen. Im Menü gibt es jetzt auch einen Bereich für gezielte Sicherung einzelner Bereiche (DB, Media, Static, Image, Config). Die Zurück-Funktion ("z") ist überall verfügbar.
|
||||
|
||||
## Erweiterte Best Practice (empfohlen)
|
||||
- **Offsite-Backup:**
|
||||
- Backups werden automatisch auf ein externes System (z.B. NAS, Cloud) kopiert. Beispiel: WD MyCloud EX2 Ultra unter 192.168.178.100.
|
||||
- **Benachrichtigung:**
|
||||
- Nach jedem Backup/Restore kann eine E-Mail oder Slack-Nachricht über Erfolg oder Fehler verschickt werden.
|
||||
- **Regelmäßiger Restore-Test:**
|
||||
- Ein Test-Restore-Skript prüft regelmäßig, ob Backups erfolgreich wiederhergestellt werden können.
|
||||
- **Versionsverwaltung der Skripte:**
|
||||
- Die Skripte selbst werden in einem Git-Repository versioniert (z.B. auf deinem Gitea-Server), um Änderungen nachverfolgen zu können.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
find /home/thomas/backup_images/* -maxdepth 0 -type d -mtime +14 -exec rm -rf {} \;
|
||||
echo "Alte Backups (älter als 14 Tage) wurden gelöscht."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Nutzung: $0 <containername> <root-passwort>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONTAINER=$1
|
||||
PASS=$2
|
||||
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="/home/thomas/backup_images/single_db_dumps"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
docker exec $CONTAINER mysqldump -u root -p$PASS --all-databases --single-transaction --quick --lock-tables=false > "$BACKUP_DIR/${CONTAINER}_$DATE.sql"
|
||||
echo "Dump gespeichert unter $BACKUP_DIR/${CONTAINER}_$DATE.sql"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Achtung: Dies entfernt alle nicht verwendeten Container, Images und Volumes!"
|
||||
read -p "Fortfahren? (ja/nein): " confirm
|
||||
if [ "$confirm" != "ja" ]; then
|
||||
echo "Abgebrochen."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
docker system prune -a --volumes
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Bitte gib den Containernamen an!"
|
||||
echo "Beispiel: $0 nginx"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker logs --tail 100 $1
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Laufende Container:"
|
||||
docker ps
|
||||
|
||||
echo
|
||||
|
||||
echo "Alle Container (inkl. gestoppte):"
|
||||
docker ps -a
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Backup-Skript für Docker-Umgebung nach Best Practice
|
||||
# Sichert: Docker-Images, Volumes, Konfigs, MariaDB-Dumps (automatisch aus db_uebersicht.md)
|
||||
# Ziel: /home/thomas/backup_images/<DATUM_UHRZEIT>/
|
||||
|
||||
set -e
|
||||
|
||||
BACKUP_ROOT="/home/thomas/backup_images"
|
||||
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
|
||||
BACKUP_DIR="$BACKUP_ROOT/$TIMESTAMP"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 1. docker-compose.yml und wichtige Konfigs sichern
|
||||
cp /home/thomas/docker-compose.yml "$BACKUP_DIR/"
|
||||
cp /home/thomas/nginx_docker_setup.md "$BACKUP_DIR/" 2>/dev/null || true
|
||||
cp /home/thomas/SYSTEM_INFO_DOCKER.txt "$BACKUP_DIR/" 2>/dev/null || true
|
||||
cp /home/thomas/container/nginx/nginx.conf "$BACKUP_DIR/" 2>/dev/null || true
|
||||
|
||||
# 2. Docker-Images sichern
|
||||
mkdir -p "$BACKUP_DIR/images"
|
||||
docker images --format '{{.Repository}}:{{.Tag}}' | grep -v "<none>" | while read IMAGE; do
|
||||
SAFE_IMAGE=$(echo $IMAGE | tr '/:' '_')
|
||||
docker save "$IMAGE" | gzip > "$BACKUP_DIR/images/${SAFE_IMAGE}.tar.gz"
|
||||
done
|
||||
|
||||
# 3. MariaDB-Dumps automatisch aus db_uebersicht.md
|
||||
mkdir -p "$BACKUP_DIR/db_dumps"
|
||||
DB_UEBERSICHT="/home/thomas/db_uebersicht.md"
|
||||
tail -n +5 "$DB_UEBERSICHT" | grep -v '^$' | while IFS='|' read -r _ app db_host port user pass _ _ _; do
|
||||
db_host=$(echo "$db_host" | xargs)
|
||||
user=$(echo "$user" | xargs)
|
||||
pass=$(echo "$pass" | xargs)
|
||||
if [[ -n "$db_host" && -n "$user" && -n "$pass" && "$db_host" != "DB-Host" ]]; then
|
||||
DUMP_FILE="$BACKUP_DIR/db_dumps/${db_host}.sql"
|
||||
echo "Erstelle Dump für $db_host ($user)..."
|
||||
docker exec $db_host mysqldump -u $user -p$pass --all-databases --single-transaction --quick --lock-tables=false > "$DUMP_FILE" \
|
||||
|| echo "Fehler beim Dump von $db_host"
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. Volumes & wichtige Daten sichern (ohne MariaDB-DB-Volumes)
|
||||
mkdir -p "$BACKUP_DIR/volumes"
|
||||
# Webshop Media/Static/Templates
|
||||
cd /home/thomas/container/webshop/cleanbuild
|
||||
tar czf "$BACKUP_DIR/volumes/webshop_media.tar.gz" media/
|
||||
tar czf "$BACKUP_DIR/volumes/webshop_staticfiles.tar.gz" staticfiles/
|
||||
tar czf "$BACKUP_DIR/volumes/webshop_templates.tar.gz" templates/
|
||||
# SSV Media/Static
|
||||
cd /home/thomas/container/ssv/html
|
||||
tar czf "$BACKUP_DIR/volumes/ssv_media.tar.gz" media/
|
||||
tar czf "$BACKUP_DIR/volumes/ssv_staticfiles.tar.gz" staticfiles/
|
||||
|
||||
# 5. Let's Encrypt Zertifikate sichern (optional, falls Rechte vorhanden)
|
||||
if [ -d "/etc/letsencrypt/live/kasimirat.de" ]; then
|
||||
mkdir -p "$BACKUP_DIR/letsencrypt"
|
||||
cp -r /etc/letsencrypt/live/kasimirat.de "$BACKUP_DIR/letsencrypt/" 2>/dev/null || true
|
||||
cp -r /etc/letsencrypt/archive/kasimirat.de "$BACKUP_DIR/letsencrypt/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 6. Container-Infos sichern
|
||||
mkdir -p "$BACKUP_DIR/container_info"
|
||||
docker ps -a > "$BACKUP_DIR/container_info/docker_ps_a.txt"
|
||||
docker inspect $(docker ps -aq) > "$BACKUP_DIR/container_info/docker_inspect.json"
|
||||
|
||||
echo "Backup abgeschlossen: $BACKUP_DIR"
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
#!/bin/bash
|
||||
|
||||
GITEA_URL="https://gitea.kasimirat.de"
|
||||
GITEA_USER="thomas"
|
||||
GITEA_TOKEN="289ac11a4ad2938fa34e6baa29bec74bdbcbb57b"
|
||||
|
||||
validate_repo_name() {
|
||||
local name="$1"
|
||||
# Leerzeichen durch Bindestrich ersetzen
|
||||
name="${name// /-}"
|
||||
# Prüfen auf erlaubte Zeichen
|
||||
if [[ ! "$name" =~ ^[A-Za-z0-9._-]+$ ]]; then
|
||||
echo "Ungültiger Repo-Name! Nur Buchstaben, Zahlen, Bindestrich (-), Unterstrich (_) und Punkt (.) sind erlaubt."
|
||||
return 1
|
||||
fi
|
||||
echo "$name"
|
||||
}
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo "==== Git & Gitea Menü ===="
|
||||
echo "1) Repository klonen"
|
||||
echo "2) Status anzeigen"
|
||||
echo "3) Pull"
|
||||
echo "4) Push"
|
||||
echo "5) Branch wechseln"
|
||||
echo "6) Commit"
|
||||
echo "7) Gitea: Repo-Liste anzeigen"
|
||||
echo "8) Gitea: Neues Repo anlegen"
|
||||
echo "9) Gitea: Issue anzeigen"
|
||||
echo "10) Gitea: Issue erstellen"
|
||||
echo "q) Beenden"
|
||||
echo
|
||||
read -p "Bitte Auswahl eingeben: " auswahl
|
||||
|
||||
case $auswahl in
|
||||
1)
|
||||
read -p "Repo-URL (z.B. https://gitea.kasimirat.de/thomas/repo.git, z für zurück): " url
|
||||
[[ "$url" =~ ^[zZ]$ ]] && continue
|
||||
repo_name=$(basename -s .git "$url")
|
||||
valid_name=$(validate_repo_name "$repo_name") || { read -p "Weiter mit Enter..."; continue; }
|
||||
url_valid=$(echo "$url" | sed "s|$repo_name|$valid_name|")
|
||||
git clone "$url_valid"
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
2)
|
||||
git status
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
3)
|
||||
git pull
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
4)
|
||||
git push
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
5)
|
||||
git branch
|
||||
read -p "Branch-Name (z für zurück): " br
|
||||
[[ "$br" =~ ^[zZ]$ ]] && continue
|
||||
git checkout "$br"
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
6)
|
||||
git status
|
||||
read -p "Commit-Message (z für zurück): " msg
|
||||
[[ "$msg" =~ ^[zZ]$ ]] && continue
|
||||
git add .
|
||||
git commit -m "$msg"
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
7)
|
||||
curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_URL/api/v1/user/repos" | jq '.[] | .full_name'
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
8)
|
||||
read -p "Neuer Repo-Name (z für zurück): " repo
|
||||
[[ "$repo" =~ ^[zZ]$ ]] && continue
|
||||
valid_name=$(validate_repo_name "$repo") || { read -p "Weiter mit Enter..."; continue; }
|
||||
curl -s -X POST -H "Content-Type: application/json" -H "Authorization: token $GITEA_TOKEN" \
|
||||
-d '{"name":"'$valid_name'","private":false}' "$GITEA_URL/api/v1/user/repos" > /dev/null
|
||||
echo "Repository mit dem Namen $valid_name wurde angelegt."
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
9)
|
||||
read -p "Repo (z.B. thomas/repo, z für zurück): " repo
|
||||
[[ "$repo" =~ ^[zZ]$ ]] && continue
|
||||
user_part=$(echo "$repo" | cut -d'/' -f1)
|
||||
repo_part=$(echo "$repo" | cut -d'/' -f2)
|
||||
valid_repo_part=$(validate_repo_name "$repo_part") || { read -p "Weiter mit Enter..."; continue; }
|
||||
repo_valid="$user_part/$valid_repo_part"
|
||||
read -p "Issue-Nummer (z für zurück): " num
|
||||
[[ "$num" =~ ^[zZ]$ ]] && continue
|
||||
curl -s -H "Authorization: token $GITEA_TOKEN" "$GITEA_URL/api/v1/repos/$repo_valid/issues/$num" | jq
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
10)
|
||||
read -p "Repo (z.B. thomas/repo, z für zurück): " repo
|
||||
[[ "$repo" =~ ^[zZ]$ ]] && continue
|
||||
user_part=$(echo "$repo" | cut -d'/' -f1)
|
||||
repo_part=$(echo "$repo" | cut -d'/' -f2)
|
||||
valid_repo_part=$(validate_repo_name "$repo_part") || { read -p "Weiter mit Enter..."; continue; }
|
||||
repo_valid="$user_part/$valid_repo_part"
|
||||
read -p "Titel (z für zurück): " titel
|
||||
[[ "$titel" =~ ^[zZ]$ ]] && continue
|
||||
read -p "Beschreibung (z für zurück): " desc
|
||||
[[ "$desc" =~ ^[zZ]$ ]] && continue
|
||||
curl -s -X POST -H "Content-Type: application/json" -H "Authorization: token $GITEA_TOKEN" \
|
||||
-d '{"title":"'$titel'","body":"'$desc'"}' "$GITEA_URL/api/v1/repos/$repo_valid/issues" > /dev/null
|
||||
echo "Issue erstellt."
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
q)
|
||||
echo "Beende Menü."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Ungültige Auswahl."
|
||||
read -p "Weiter mit Enter..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
|
||||
GITEA_URL="https://gitea.kasimirat.de"
|
||||
GITEA_USER="thomas"
|
||||
GITEA_TOKEN="289ac11a4ad2938fa34e6baa29bec74bdbcbb57b"
|
||||
|
||||
read -p "Pfad zum lokalen Verzeichnis (z für Abbruch): " DIR
|
||||
[[ "$DIR" =~ ^[zZ]$ ]] && exit 0
|
||||
if [ ! -d "$DIR" ]; then
|
||||
echo "Verzeichnis nicht gefunden!"
|
||||
exit 1
|
||||
fi
|
||||
cd "$DIR"
|
||||
|
||||
read -p "Neuer Repo-Name auf Gitea (z für Abbruch): " REPO
|
||||
[[ "$REPO" =~ ^[zZ]$ ]] && exit 0
|
||||
# Repo-Name validieren (wie im Menü)
|
||||
REPO_VALID=$(echo "$REPO" | sed 's/ /-/g')
|
||||
if [[ ! "$REPO_VALID" =~ ^[A-Za-z0-9._-]+$ ]]; then
|
||||
echo "Ungültiger Repo-Name! Nur Buchstaben, Zahlen, Bindestrich (-), Unterstrich (_) und Punkt (.) sind erlaubt."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Repo per API anlegen
|
||||
ANTWORT=$(curl -s -X POST -H "Content-Type: application/json" -H "Authorization: token $GITEA_TOKEN" \
|
||||
-d '{"name":"'$REPO_VALID'","private":false}' "$GITEA_URL/api/v1/user/repos")
|
||||
if echo "$ANTWORT" | grep -q '"id"'; then
|
||||
echo "Gitea-Repo $REPO_VALID wurde angelegt."
|
||||
else
|
||||
echo "Fehler beim Anlegen des Repos: $ANTWORT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Git-Repo initialisieren (falls noch nicht vorhanden)
|
||||
if [ ! -d .git ]; then
|
||||
git init
|
||||
fi
|
||||
|
||||
git remote remove origin 2>/dev/null
|
||||
GITURL="$GITEA_URL/$GITEA_USER/$REPO_VALID.git"
|
||||
git remote add origin "$GITURL"
|
||||
|
||||
git add .
|
||||
read -p "Commit-Message: " MSG
|
||||
[[ "$MSG" =~ ^[zZ]$ ]] && exit 0
|
||||
git commit -m "$MSG"
|
||||
|
||||
git branch -M main 2>/dev/null
|
||||
|
||||
git push -u origin main
|
||||
|
||||
echo "Upload abgeschlossen. Repo: $GITURL"
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Restore-Skript für Docker-Backups
|
||||
# Nutzt einen Backup-Ordner aus /home/thomas/backup_images/<DATUM_UHRZEIT>
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Bitte gib den Backup-Ordner als Argument an!"
|
||||
echo "Beispiel: $0 2024-07-01_12-00-00"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_ROOT="/home/thomas/backup_images"
|
||||
BACKUP_DIR="$BACKUP_ROOT/$1"
|
||||
|
||||
if [ ! -d "$BACKUP_DIR" ]; then
|
||||
echo "Backup-Ordner nicht gefunden: $BACKUP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 1. Images wiederherstellen
|
||||
if [ -d "$BACKUP_DIR/images" ]; then
|
||||
for IMG in "$BACKUP_DIR/images"/*.tar.gz; do
|
||||
echo "Importiere Image: $IMG"
|
||||
gunzip -c "$IMG" | docker load
|
||||
done
|
||||
fi
|
||||
|
||||
# 2. Volumes wiederherstellen (Achtung: überschreibt aktuelle Daten!)
|
||||
# Beispiel für Webshop Media/Static/Templates
|
||||
if [ -f "$BACKUP_DIR/volumes/webshop_media.tar.gz" ]; then
|
||||
echo "Stelle Webshop Media wieder her..."
|
||||
tar xzf "$BACKUP_DIR/volumes/webshop_media.tar.gz" -C /home/thomas/container/webshop/cleanbuild
|
||||
fi
|
||||
if [ -f "$BACKUP_DIR/volumes/webshop_staticfiles.tar.gz" ]; then
|
||||
echo "Stelle Webshop Staticfiles wieder her..."
|
||||
tar xzf "$BACKUP_DIR/volumes/webshop_staticfiles.tar.gz" -C /home/thomas/container/webshop/cleanbuild
|
||||
fi
|
||||
if [ -f "$BACKUP_DIR/volumes/webshop_templates.tar.gz" ]; then
|
||||
echo "Stelle Webshop Templates wieder her..."
|
||||
tar xzf "$BACKUP_DIR/volumes/webshop_templates.tar.gz" -C /home/thomas/container/webshop/cleanbuild
|
||||
fi
|
||||
# SSV Media/Static
|
||||
if [ -f "$BACKUP_DIR/volumes/ssv_media.tar.gz" ]; then
|
||||
echo "Stelle SSV Media wieder her..."
|
||||
tar xzf "$BACKUP_DIR/volumes/ssv_media.tar.gz" -C /home/thomas/container/ssv/html
|
||||
fi
|
||||
if [ -f "$BACKUP_DIR/volumes/ssv_staticfiles.tar.gz" ]; then
|
||||
echo "Stelle SSV Staticfiles wieder her..."
|
||||
tar xzf "$BACKUP_DIR/volumes/ssv_staticfiles.tar.gz" -C /home/thomas/container/ssv/html
|
||||
fi
|
||||
|
||||
# 3. DB-Dumps importieren (automatisch aus db_uebersicht.md)
|
||||
DB_UEBERSICHT="/home/thomas/db_uebersicht.md"
|
||||
DUMP_DIR="$BACKUP_DIR/db_dumps"
|
||||
if [ -d "$DUMP_DIR" ]; then
|
||||
tail -n +5 "$DB_UEBERSICHT" | grep -v '^$' | while IFS='|' read -r _ app db_host port user pass _ _ _; do
|
||||
db_host=$(echo "$db_host" | xargs)
|
||||
user=$(echo "$user" | xargs)
|
||||
pass=$(echo "$pass" | xargs)
|
||||
if [[ -n "$db_host" && -n "$user" && -n "$pass" && "$db_host" != "DB-Host" ]]; then
|
||||
DUMP_FILE="$DUMP_DIR/${db_host}.sql"
|
||||
if [ -f "$DUMP_FILE" ]; then
|
||||
echo "Importiere Dump für $db_host ($user)..."
|
||||
cat "$DUMP_FILE" | docker exec -i $db_host mysql -u $user -p$pass || echo "Fehler beim Import in $db_host"
|
||||
else
|
||||
echo "Kein Dump für $db_host gefunden: $DUMP_FILE"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# 4. Konfigs wiederherstellen (manuell prüfen!)
|
||||
# cp "$BACKUP_DIR/docker-compose.yml" /home/thomas/docker-compose.yml
|
||||
# cp "$BACKUP_DIR/nginx.conf" /home/thomas/container/nginx/nginx.conf
|
||||
|
||||
# 5. Zertifikate (optional)
|
||||
# cp -r "$BACKUP_DIR/letsencrypt"/* /etc/letsencrypt/
|
||||
|
||||
echo "Restore abgeschlossen. Bitte prüfe die Konfigurationen und starte ggf. die Container neu!"
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
#!/bin/bash
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo "==== Backup & Restore Menü ===="
|
||||
echo "1) Komplettes Backup erstellen"
|
||||
echo "2) Komplettes Restore durchführen"
|
||||
echo "3) Einzelne Bereiche sichern (DB, Media, Static, Image, Config)"
|
||||
echo "4) Einzelne Datenbank wiederherstellen"
|
||||
echo "5) Media-Dateien wiederherstellen"
|
||||
echo "6) Staticfiles wiederherstellen"
|
||||
echo "7) Docker-Image importieren"
|
||||
echo "8) Konfigurationsdatei wiederherstellen"
|
||||
echo "q) Beenden"
|
||||
echo
|
||||
read -p "Bitte Auswahl eingeben: " auswahl
|
||||
|
||||
case $auswahl in
|
||||
1)
|
||||
/home/thomas/scripte/backup_docker.sh
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
2)
|
||||
read -p "Backup-Zeitstempel (z für zurück): " ts
|
||||
[[ "$ts" =~ ^[zZ]$ ]] && continue
|
||||
/home/thomas/scripte/restore_docker.sh "$ts"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
3)
|
||||
while true; do
|
||||
clear
|
||||
echo "--- Einzelne Bereiche sichern ---"
|
||||
echo "a) Einzelne Datenbank sichern"
|
||||
echo "b) Media sichern"
|
||||
echo "c) Staticfiles sichern"
|
||||
echo "d) Docker-Image sichern"
|
||||
echo "e) Konfigurationsdatei sichern"
|
||||
echo "z) Zurück"
|
||||
echo
|
||||
read -p "Bitte Auswahl eingeben: " sub
|
||||
case $sub in
|
||||
a)
|
||||
read -p "Containername (z für zurück): " ctn
|
||||
[[ "$ctn" =~ ^[zZ]$ ]] && break
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/backup_db.sh "$ctn"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && break
|
||||
;;
|
||||
b)
|
||||
read -p "Projekt (webshop|ssv, z für zurück): " prj
|
||||
[[ "$prj" =~ ^[zZ]$ ]] && break
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/backup_media.sh "$prj"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && break
|
||||
;;
|
||||
c)
|
||||
read -p "Projekt (webshop|ssv, z für zurück): " prj
|
||||
[[ "$prj" =~ ^[zZ]$ ]] && break
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/backup_staticfiles.sh "$prj"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && break
|
||||
;;
|
||||
d)
|
||||
read -p "Image-Name (z.B. nginx:latest, z für zurück): " img
|
||||
[[ "$img" =~ ^[zZ]$ ]] && break
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/backup_image.sh "$img"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && break
|
||||
;;
|
||||
e)
|
||||
read -p "Datei (docker-compose.yml|nginx.conf, z für zurück): " datei
|
||||
[[ "$datei" =~ ^[zZ]$ ]] && break
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/backup_config.sh "$datei"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && break
|
||||
;;
|
||||
z|Z)
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Ungültige Auswahl."
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
4)
|
||||
read -p "Backup-Zeitstempel (z für zurück): " ts
|
||||
[[ "$ts" =~ ^[zZ]$ ]] && continue
|
||||
read -p "Containername (z.B. db_webshop, z für zurück): " ctn
|
||||
[[ "$ctn" =~ ^[zZ]$ ]] && continue
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/restore_db.sh "$ts" "$ctn"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
5)
|
||||
read -p "Backup-Zeitstempel (z für zurück): " ts
|
||||
[[ "$ts" =~ ^[zZ]$ ]] && continue
|
||||
read -p "Projekt (webshop|ssv, z für zurück): " prj
|
||||
[[ "$prj" =~ ^[zZ]$ ]] && continue
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/restore_media.sh "$ts" "$prj"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
6)
|
||||
read -p "Backup-Zeitstempel (z für zurück): " ts
|
||||
[[ "$ts" =~ ^[zZ]$ ]] && continue
|
||||
read -p "Projekt (webshop|ssv, z für zurück): " prj
|
||||
[[ "$prj" =~ ^[zZ]$ ]] && continue
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/restore_staticfiles.sh "$ts" "$prj"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
7)
|
||||
read -p "Backup-Zeitstempel (z für zurück): " ts
|
||||
[[ "$ts" =~ ^[zZ]$ ]] && continue
|
||||
read -p "Image-Name (z.B. nginx_latest, z für zurück): " img
|
||||
[[ "$img" =~ ^[zZ]$ ]] && continue
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/restore_image.sh "$ts" "$img"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
8)
|
||||
read -p "Backup-Zeitstempel (z für zurück): " ts
|
||||
[[ "$ts" =~ ^[zZ]$ ]] && continue
|
||||
read -p "Datei (docker-compose.yml|nginx.conf, z für zurück): " datei
|
||||
[[ "$datei" =~ ^[zZ]$ ]] && continue
|
||||
/home/thomas/scripte/Einzelne_Restore_Scripte/restore_config.sh "$ts" "$datei"
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
q)
|
||||
echo "Beende Menü."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Ungültige Auswahl."
|
||||
read -p "Weiter mit Enter... (z für zurück)" z; [[ "$z" =~ ^[zZ]$ ]] && continue
|
||||
;;
|
||||
esac
|
||||
done
|
||||
Loading…
Reference in New Issue