v0.2 Alpha Release
This commit is contained in:
@@ -1,113 +1,150 @@
|
||||
# StFV Backup
|
||||
# BackItUp
|
||||
|
||||
Flask-basierte Backup-Verwaltung für SMB, LOCAL, FTP und SFTP – mit Web-UI, Zeitplan-Steuerung und Sync/Clone-Modus.
|
||||
## Überblick
|
||||
|
||||
BackItUp ist eine webbasierte Anwendung zur Verwaltung automatischer Datei-Backups.
|
||||
Sie läuft als Hintergrunddienst auf einem Linux-Server und ist über einen Browser erreichbar.
|
||||
|
||||
- **Technologie**: Python 3 / Flask (Webanwendung)
|
||||
- **Oberfläche**: Web-UI im Browser (kein Programmieren nötig)
|
||||
- **Datenbank**: SQLite (wird automatisch angelegt unter `data/config.db`)
|
||||
- **Dienst**: systemd-User-Service (läuft automatisch im Hintergrund)
|
||||
- **Standard-Adresse**: `http://127.0.0.1:5001/`
|
||||
- **Einstiegspunkt**: `main.py`
|
||||
|
||||
---
|
||||
|
||||
## Schnellstart
|
||||
## Hintergrund / Wozu dient das?
|
||||
|
||||
Das Tool ermöglicht es, Dateien von einem Ort (Quelle) regelmäßig an einen anderen Ort (Ziel) zu kopieren – vollautomatisch nach einem selbst definierten Zeitplan.
|
||||
|
||||
Typische Anwendungsfälle:
|
||||
- Dateien von einem Netzlaufwerk (SMB) auf einen lokalen Server sichern
|
||||
- Inhalte per SFTP oder FTP auf einen entfernten Server übertragen
|
||||
- Regelmäßige Spiegelung eines Verzeichnisses (Sync/Clone)
|
||||
|
||||
Die Konfiguration erfolgt komplett über die Weboberfläche – kein Editieren von Konfigurationsdateien nötig.
|
||||
|
||||
---
|
||||
|
||||
## Schnellstart (erster Start / Entwicklung)
|
||||
|
||||
Beim allerersten Aufruf ohne vorhandene Konfiguration richtet das System sich selbst ein:
|
||||
|
||||
```bash
|
||||
# Einmalig: Venv anlegen, Abhängigkeiten installieren, Ersteinrichtung starten
|
||||
python3 main.py
|
||||
|
||||
# Deployment auf einem Linux-Server (systemd)
|
||||
python3 main.py --setup
|
||||
systemctl --user enable nextcloud-backup
|
||||
systemctl --user start nextcloud-backup
|
||||
```
|
||||
|
||||
Nach dem Start ist die Oberfläche erreichbar unter:
|
||||
Das Programm fragt dann interaktiv ab:
|
||||
- **IP und Port** des Webservers (z. B. `0.0.0.0` und `5001`)
|
||||
- **Admin-Benutzername und Passwort** für den Login im Browser
|
||||
|
||||
Danach ist die Oberfläche erreichbar unter:
|
||||
`http://<IP>:<Port>/` (Standard: `http://127.0.0.1:5001/`)
|
||||
|
||||
---
|
||||
|
||||
## Deployment auf Oracle Linux / RHEL
|
||||
## Deployment auf einem Linux-Server (produktiv)
|
||||
|
||||
Für den dauerhaften Betrieb wird die Anwendung als systemd-Dienst eingerichtet.
|
||||
Der Dienst startet automatisch beim Booten und läuft auch ohne aktive Anmeldesitzung.
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
```bash
|
||||
# Python, pip und git installieren (Oracle Linux / RHEL)
|
||||
sudo dnf install python3 python3-pip git -y
|
||||
# Service soll auch ohne aktive Login-Session laufen
|
||||
|
||||
# Sicherstellen, dass der Dienst auch ohne Login läuft
|
||||
sudo loginctl enable-linger $USER
|
||||
```
|
||||
|
||||
### Projekt klonen und einrichten
|
||||
|
||||
```bash
|
||||
git clone https://gitea.example.com/user/stfv-backup.git ~/stfv-backup
|
||||
cd ~/stfv-backup
|
||||
git clone git@10.11.12.66:EDV/BackItUp.git ~/BackItUp
|
||||
cd ~/BackItUp
|
||||
python3 main.py --setup
|
||||
```
|
||||
|
||||
`--setup` erledigt automatisch:
|
||||
1. Virtuelle Umgebung unter `.venv/` anlegen
|
||||
2. Abhängigkeiten installieren
|
||||
3. systemd-User-Service unter `~/.config/systemd/user/nextcloud-backup.service` schreiben (mit echten Pfaden)
|
||||
1. Virtuelle Python-Umgebung unter `.venv/` anlegen
|
||||
2. Alle Abhängigkeiten installieren
|
||||
3. systemd-User-Service unter `~/.config/systemd/user/BackItUp.service` schreiben (mit korrekten Pfaden)
|
||||
4. `systemctl --user daemon-reload` ausführen
|
||||
|
||||
### Service aktivieren
|
||||
### Dienst aktivieren und starten
|
||||
|
||||
```bash
|
||||
systemctl --user enable nextcloud-backup
|
||||
systemctl --user start nextcloud-backup
|
||||
systemctl --user status nextcloud-backup
|
||||
journalctl --user -u nextcloud-backup -f
|
||||
systemctl --user enable BackItUp # Autostart beim Booten aktivieren
|
||||
systemctl --user start BackItUp # Dienst jetzt starten
|
||||
systemctl --user status BackItUp # Aktuellen Status anzeigen
|
||||
journalctl --user -u BackItUp -f # Live-Log verfolgen
|
||||
```
|
||||
|
||||
### Beim ersten Start
|
||||
|
||||
Beim allerersten Aufruf ohne Konfiguration fragt das System interaktiv ab:
|
||||
- IP und Port des Flask-Servers
|
||||
- Admin-Benutzername und Passwort (wird als PBKDF2-SHA256-Hash gespeichert)
|
||||
|
||||
---
|
||||
|
||||
## Funktionsübersicht
|
||||
|
||||
### Backup-Modi
|
||||
|
||||
Es gibt drei Betriebsmodi, die sich im Umgang mit bereits vorhandenen Zieldateien unterscheiden:
|
||||
|
||||
| Modus | Verhalten |
|
||||
|---|---|
|
||||
| **Vollständig** | Alle Dateien aus der Quelle werden jedes Mal übertragen |
|
||||
| **Sync** | Nur neue oder geänderte Dateien (Vergleich per Größe + mtime) |
|
||||
| **Clone** | Wie Sync, zusätzlich werden Dateien im Ziel gelöscht die in der Quelle nicht mehr existieren |
|
||||
| **Vollständig** | Alle Dateien aus der Quelle werden jedes Mal übertragen (neue Kopie) |
|
||||
| **Sync** | Nur neue oder geänderte Dateien werden übertragen (Vergleich per Größe + Änderungsdatum) |
|
||||
| **Clone** | Wie Sync, aber Dateien im Ziel, die in der Quelle nicht mehr existieren, werden gelöscht |
|
||||
|
||||
### Unterstützte Protokolle
|
||||
> Faustregel: **Vollständig** für versionierte Snapshots, **Sync** für einfache Spiegelung, **Clone** für exakte 1:1-Kopie.
|
||||
|
||||
- **SMB** – mit integriertem Verzeichnis-Browser und Ordner-Erstellung
|
||||
- **LOCAL** – lokales Dateisystem mit Browser und Ordner-Erstellung
|
||||
- **FTP** – mit konfigurierbarem Port (Standard: 21)
|
||||
- **SFTP** – SSH-basiert (Standard-Port: 22)
|
||||
### Unterstützte Protokolle / Verbindungsarten
|
||||
|
||||
### Zeitplan
|
||||
| Protokoll | Beschreibung |
|
||||
|---|---|
|
||||
| **SMB** | Windows-Netzlaufwerke; mit integriertem Verzeichnis-Browser |
|
||||
| **LOCAL** | Lokales Dateisystem des Servers; mit Verzeichnis-Browser |
|
||||
| **FTP** | Standard-FTP; Port konfigurierbar (Standard: 21) |
|
||||
| **SFTP** | SSH-basierte Dateiübertragung (Standard-Port: 22) |
|
||||
|
||||
- CRON-Ausdruck frei definierbar (z. B. `0 2 * * *` für täglich um 02:00 Uhr)
|
||||
- CRON-Vorschau im Wizard zeigt den nächsten geplanten Zeitpunkt
|
||||
- Leer lassen = nur manuelles Backup möglich
|
||||
- „Nächster Lauf" im Dashboard wird nach jedem Backup automatisch aktualisiert
|
||||
### Zeitplan (CRON)
|
||||
|
||||
### Rotation
|
||||
Der Backup-Zeitplan wird als CRON-Ausdruck angegeben.
|
||||
Die Oberfläche zeigt dabei eine Vorschau des nächsten geplanten Zeitpunkts an.
|
||||
|
||||
- Anzahl aufzubewahrender Backups konfigurierbar
|
||||
Beispiele:
|
||||
- `0 2 * * *` → täglich um 02:00 Uhr
|
||||
- `0 */6 * * *` → alle 6 Stunden
|
||||
- *(leer lassen)* → kein automatischer Lauf, nur manuelles Backup möglich
|
||||
|
||||
### Rotation (nur Modus „Vollständig")
|
||||
|
||||
- Legt fest, wie viele Backup-Kopien aufbewahrt werden
|
||||
- Ältere Kopien werden automatisch gelöscht, sobald der Wert überschritten wird
|
||||
- `0` = unbegrenzt (keine automatische Löschung)
|
||||
- Nur bei Modus **Vollständig** verfügbar (Sync/Clone verwalten den Zustand selbst)
|
||||
- Im Sync/Clone-Modus nicht verfügbar, da dort kein Versionsarchiv angelegt wird
|
||||
|
||||
### Kompression & Verschlüsselung
|
||||
|
||||
Backups können wahlweise komprimiert und/oder mit einem Passwort gesichert werden:
|
||||
|
||||
| Methode | Unterstützt |
|
||||
|---|---|
|
||||
| Keine (1:1 Kopie) | ✅ |
|
||||
| zip | ✅ |
|
||||
| tar.gz / tar.bz2 / tar.xz | ✅ |
|
||||
| 7z | ✅ (py7zr erforderlich) |
|
||||
| 7z | ✅ (`py7zr` ist bereits in `requirements.txt` enthalten) |
|
||||
| AES-256 Archiv-Passwort | ✅ |
|
||||
|
||||
### Sicherheit
|
||||
---
|
||||
|
||||
- Passwörter werden nie im Klartext gespeichert
|
||||
- Benutzerpasswörter: PBKDF2-SHA256
|
||||
- Verbindungspasswörter: AES-verschlüsselt in der Datenbank
|
||||
- Session-basierter Login mit Rollen (Admin / Benutzer)
|
||||
## Sicherheitsmodell
|
||||
|
||||
Zugangsdaten werden grundsätzlich nie im Klartext gespeichert:
|
||||
|
||||
- **Benutzerpasswörter** (Login): PBKDF2-SHA256-Hash
|
||||
- **Verbindungspasswörter** (SMB, FTP usw.): AES-256-verschlüsselt in der Datenbank
|
||||
- **Session-Login**: rollenbasiert (Admin / Benutzer)
|
||||
|
||||
---
|
||||
|
||||
@@ -119,43 +156,60 @@ app/
|
||||
app_runner.py # Bootstrap, Setup-Logik, systemd-Installation
|
||||
web_server.py # Flask-Routen, Backup-Ausführung, Scheduler
|
||||
config_store.py # SQLite-Schema, Migrationen, CRUD
|
||||
config_model.py # Dataclasses
|
||||
remote_targets.py # Verbindungstests, Browser-Helfer
|
||||
config_model.py # Datenklassen (Backup-Jobs, Benutzer usw.)
|
||||
remote_targets.py # Verbindungstests, Verzeichnis-Browser
|
||||
setup_wizard.py # Interaktive Erstkonfiguration (CLI)
|
||||
venv_manager.py # Venv-Prüfung und Re-Exec
|
||||
dependencies.py # Paketinstallation
|
||||
venv_manager.py # Venv-Prüfung und automatischer Re-Start
|
||||
dependencies.py # Automatische Paketinstallation
|
||||
security.py # Passwort-Hashing
|
||||
paths.py # Zentrale Pfadverwaltung
|
||||
ui.py # Konsolenausgabe
|
||||
templates/ # Jinja2-Templates (Dashboard, Wizard, ...)
|
||||
ui.py # Konsolenausgabe (Farben, Fortschritt)
|
||||
templates/ # HTML-Vorlagen für die Weboberfläche
|
||||
data/
|
||||
config.db # SQLite-Datenbank (wird automatisch angelegt)
|
||||
config.db # SQLite-Datenbank (wird beim ersten Start angelegt)
|
||||
deploy/
|
||||
systemd/
|
||||
nextcloud-backup.service # Vorlage; --setup schreibt echte Pfade
|
||||
BackItUp.service # Vorlage; --setup schreibt die echten Pfade
|
||||
scripts/
|
||||
service.sh # Manuelle Service-Verwaltung (Alternative zu --setup)
|
||||
requirements.txt
|
||||
requirements.txt # Python-Abhängigkeiten
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service manuell verwalten
|
||||
## Betrieb
|
||||
|
||||
### Dienst manuell verwalten
|
||||
|
||||
Das Script `scripts/service.sh` bietet eine komfortable Alternative zu den systemctl-Befehlen:
|
||||
|
||||
```bash
|
||||
./scripts/service.sh install # Service-Datei installieren + daemon-reload
|
||||
./scripts/service.sh start
|
||||
./scripts/service.sh stop
|
||||
./scripts/service.sh restart
|
||||
./scripts/service.sh status
|
||||
./scripts/service.sh logs
|
||||
./scripts/service.sh start # Dienst starten
|
||||
./scripts/service.sh stop # Dienst stoppen
|
||||
./scripts/service.sh restart # Dienst neu starten
|
||||
./scripts/service.sh status # Aktuellen Status anzeigen
|
||||
./scripts/service.sh logs # Log ausgeben
|
||||
./scripts/service.sh enable # Autostart aktivieren
|
||||
./scripts/service.sh disable
|
||||
./scripts/service.sh disable # Autostart deaktivieren
|
||||
```
|
||||
|
||||
### Log live verfolgen
|
||||
|
||||
```bash
|
||||
journalctl --user -u BackItUp -f
|
||||
```
|
||||
|
||||
### Dienst-Status prüfen
|
||||
|
||||
```bash
|
||||
systemctl --user status BackItUp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anforderungen
|
||||
|
||||
- Python 3.10+
|
||||
- Abhängigkeiten: siehe `requirements.txt` (werden beim Start automatisch installiert)
|
||||
- **Python**: 3.10 oder neuer
|
||||
- **Abhängigkeiten**: werden beim ersten Start automatisch installiert (siehe `requirements.txt`)
|
||||
- **Betriebssystem**: Linux mit systemd (getestet auf Oracle Linux / RHEL)
|
||||
|
||||
+4
-4
@@ -26,7 +26,7 @@ class AppRunner:
|
||||
ConsoleUI.info("Alle Abhaengigkeiten sind bereits installiert.")
|
||||
|
||||
def setup(self) -> None:
|
||||
ConsoleUI.headline("StFV Backup Setup")
|
||||
ConsoleUI.headline("BackItUp Setup")
|
||||
self._bootstrap()
|
||||
ConsoleUI.success("System ist bereit.")
|
||||
self._install_systemd_service()
|
||||
@@ -40,7 +40,7 @@ class AppRunner:
|
||||
ConsoleUI.info("Manuelle Installation: bash scripts/service.sh install")
|
||||
return
|
||||
|
||||
service_name = "nextcloud-backup.service"
|
||||
service_name = "BackItUp.service"
|
||||
user_systemd_dir = Path.home() / ".config" / "systemd" / "user"
|
||||
user_systemd_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -50,7 +50,7 @@ class AppRunner:
|
||||
venv_python = self.paths.venv_dir / "bin" / "python"
|
||||
|
||||
service_content = f"""[Unit]
|
||||
Description=StFV Backup Flask Service
|
||||
Description=BackItUp Flask Service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
@@ -82,7 +82,7 @@ WantedBy=default.target
|
||||
ConsoleUI.info(f"Logs verfolgen: journalctl --user -u {service_name} -f")
|
||||
|
||||
def run(self) -> None:
|
||||
ConsoleUI.headline("StFV Backup Bootstrap")
|
||||
ConsoleUI.headline("BackItUp Bootstrap")
|
||||
self._bootstrap()
|
||||
|
||||
from app.config_store import ConfigStore
|
||||
|
||||
@@ -153,8 +153,8 @@ def _test_smb_with_pysmb(target: TargetConnection) -> tuple[bool, str]:
|
||||
conn = SMBConnection(
|
||||
target.username,
|
||||
target.password,
|
||||
"stfv-backup-client",
|
||||
"stfv-backup-server",
|
||||
"backitup-client",
|
||||
"backitup-server",
|
||||
use_ntlm_v2=True,
|
||||
is_direct_tcp=True,
|
||||
)
|
||||
@@ -208,8 +208,8 @@ def _browse_smb_with_pysmb(target: TargetConnection) -> tuple[bool, str, list[di
|
||||
conn = SMBConnection(
|
||||
target.username,
|
||||
target.password,
|
||||
"stfv-backup-client",
|
||||
"stfv-backup-server",
|
||||
"backitup-client",
|
||||
"backitup-server",
|
||||
use_ntlm_v2=True,
|
||||
is_direct_tcp=True,
|
||||
)
|
||||
@@ -439,8 +439,8 @@ def create_smb_directory(target: TargetConnection, base_path: str, folder_name:
|
||||
conn = SMBConnection(
|
||||
target.username,
|
||||
target.password,
|
||||
"stfv-backup-client",
|
||||
"stfv-backup-server",
|
||||
"backitup-client",
|
||||
"backitup-server",
|
||||
use_ntlm_v2=True,
|
||||
is_direct_tcp=True,
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base_admin.html" %}
|
||||
|
||||
{% block title %}StFV Backup - Admin Konto{% endblock %}
|
||||
{% block title %}BackItUp - Admin Konto{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Admin Konto</h2>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base_admin.html" %}
|
||||
|
||||
{% block title %}StFV Backup - Backup bearbeiten{% endblock %}
|
||||
{% block title %}BackItUp - Backup bearbeiten{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2 style="margin-bottom:4px;">Backup bearbeiten</h2>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base_admin.html" %}
|
||||
|
||||
{% block title %}StFV Backup - Neues Backup{% endblock %}
|
||||
{% block title %}BackItUp - Neues Backup{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2 style="margin-bottom:4px;">Neues Backup einrichten</h2>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}StFV Backup{% endblock %}</title>
|
||||
<title>{% block title %}BackItUp{% endblock %}</title>
|
||||
<style>
|
||||
:root {
|
||||
--paper: #f8fbff;
|
||||
@@ -237,7 +237,7 @@
|
||||
<main class="layout">
|
||||
<section class="panel top">
|
||||
<div>
|
||||
<h1 class="brand">StFV Backup</h1>
|
||||
<h1 class="brand">BackItUp</h1>
|
||||
<p class="sub">Angemeldet als {{ adminuser }}</p>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base_admin.html" %}
|
||||
|
||||
{% block title %}StFV Backup - Dashboard{% endblock %}
|
||||
{% block title %}BackItUp - Dashboard{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<style>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>StFV Backup - Login</title>
|
||||
<title>BackItUp - Login</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-1: #f7f9fc;
|
||||
@@ -134,7 +134,7 @@
|
||||
<body>
|
||||
<main class="shell">
|
||||
<header class="head">
|
||||
<h1>StFV Backup</h1>
|
||||
<h1>BackItUp</h1>
|
||||
</header>
|
||||
<section class="content">
|
||||
{% if error_message %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base_admin.html" %}
|
||||
|
||||
{% block title %}StFV Backup - Server Settings{% endblock %}
|
||||
{% block title %}BackItUp - Server Settings{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Server Settings</h2>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "base_admin.html" %}
|
||||
|
||||
{% block title %}StFV Backup - Benutzer{% endblock %}
|
||||
{% block title %}BackItUp - Benutzer{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Benutzerverwaltung</h2>
|
||||
|
||||
+1
-1
@@ -421,7 +421,7 @@ class FlaskServer:
|
||||
target_base = f"backup_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}"
|
||||
archive_name = self._ensure_archive_suffix(target_base, method)
|
||||
|
||||
work_dir = Path(tempfile.mkdtemp(prefix="stfv-backup-"))
|
||||
work_dir = Path(tempfile.mkdtemp(prefix="backitup-"))
|
||||
staging_dir = work_dir / "staging"
|
||||
staging_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[Unit]
|
||||
Description=StFV Backup Flask Service
|
||||
Description=BackItUp Flask Service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/home/osadmin/Nextcloud_Backup
|
||||
ExecStart=/home/osadmin/Nextcloud_Backup/.venv/bin/python /home/osadmin/Nextcloud_Backup/main.py
|
||||
WorkingDirectory=/home/osadmin/BackItUp
|
||||
ExecStart=/home/osadmin/BackItUp/.venv/bin/python /home/osadmin/BackItUp/main.py
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SERVICE_NAME="nextcloud-backup.service"
|
||||
SERVICE_NAME="BackItUp.service"
|
||||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
USER_SYSTEMD_DIR="${HOME}/.config/systemd/user"
|
||||
TARGET_SERVICE_FILE="${USER_SYSTEMD_DIR}/${SERVICE_NAME}"
|
||||
|
||||
Reference in New Issue
Block a user