initial commit

This commit is contained in:
thomas 2025-07-01 15:20:17 +02:00
commit adcaceb7ac
22 changed files with 791 additions and 0 deletions

View File

@ -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/"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

4
NAS_CREDENTIALS.txt Normal file
View File

@ -0,0 +1,4 @@
# Zugangsdaten für WD MyCloud EX2 Ultra NAS
user=backup
password=backupnuk
# Freigabe: //192.168.178.101/Backup

64
SKRIPTE_INFO.md Normal file
View File

@ -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.

View File

@ -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."

View File

@ -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"

View File

@ -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

9
Wartungsscripte/docker_logs.sh Executable file
View File

@ -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

View File

@ -0,0 +1,9 @@
#!/bin/bash
echo "Laufende Container:"
docker ps
echo
echo "Alle Container (inkl. gestoppte):"
docker ps -a

67
backup_docker.sh Executable file
View File

@ -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"

123
git_gitea_menu.sh Executable file
View File

@ -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

52
git_gitea_upload.sh Executable file
View File

@ -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"

79
restore_docker.sh Executable file
View File

@ -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!"

131
restore_menu.sh Executable file
View File

@ -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