feat: add automated backup script with Discord notifications
Daily backup at 19h, zips data/ to backup/, keeps 2 max, notifies via Discord webhook. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/data
|
||||||
|
/data_backup_*
|
||||||
|
/backup
|
||||||
|
/logs
|
||||||
|
.env
|
||||||
40
README.md
40
README.md
@@ -51,32 +51,33 @@ docker compose pull
|
|||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
## Sauvegarde
|
## Sauvegarde automatique
|
||||||
|
|
||||||
Le dossier `./data` contient toutes les donnees :
|
Un script de backup automatique est inclus : `backup-vaultwarden.sh`.
|
||||||
- `db.sqlite3` : base de donnees (comptes, mots de passe chiffres)
|
|
||||||
- `attachments/` : fichiers joints
|
|
||||||
- `sends/` : fichiers Send
|
|
||||||
- `config.json` : configuration
|
|
||||||
- `rsa_key.pem` : cle RSA du serveur
|
|
||||||
|
|
||||||
### Exporter une sauvegarde
|
- **Frequence** : tous les jours a 19h (cron)
|
||||||
|
- **Format** : zip du dossier `data/` dans `backup/`
|
||||||
|
- **Retention** : 2 backups max (rotation automatique)
|
||||||
|
- **Notification** : Discord via webhook
|
||||||
|
|
||||||
|
### Lancer manuellement
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Arreter le conteneur pour eviter la corruption de la BDD
|
./backup-vaultwarden.sh
|
||||||
docker compose down
|
|
||||||
|
|
||||||
# Copier le dossier data
|
|
||||||
cp -r ./data ./data_backup_$(date +%Y%m%d)
|
|
||||||
|
|
||||||
# Relancer
|
|
||||||
docker compose up -d
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compresser pour transfert
|
### Installer le cron
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
tar czf vaultwarden_backup_$(date +%Y%m%d).tar.gz ./data
|
crontab -e
|
||||||
|
# Ajouter :
|
||||||
|
0 19 * * * /usr/bin/bash /home/matt/vaultwarden/backup-vaultwarden.sh >> /home/matt/vaultwarden/logs/cron_vaultwarden.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sauvegarde manuelle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
zip -r vaultwarden-backup-$(date +%Y%m%d).zip ./data
|
||||||
```
|
```
|
||||||
|
|
||||||
## Restauration / Migration
|
## Restauration / Migration
|
||||||
@@ -126,9 +127,12 @@ Tout est restaure : comptes, mots de passe, fichiers joints.
|
|||||||
.
|
.
|
||||||
├── docker-compose.yml # Definition du service Docker
|
├── docker-compose.yml # Definition du service Docker
|
||||||
├── setup-vaultwarden-https.sh # Script de configuration NGINX + HTTPS
|
├── setup-vaultwarden-https.sh # Script de configuration NGINX + HTTPS
|
||||||
|
├── backup-vaultwarden.sh # Script de backup automatique
|
||||||
├── .env # Variables d'environnement (non versionne)
|
├── .env # Variables d'environnement (non versionne)
|
||||||
├── .env.example # Exemple de configuration
|
├── .env.example # Exemple de configuration
|
||||||
├── data/ # Donnees Vaultwarden (non versionne)
|
├── data/ # Donnees Vaultwarden (non versionne)
|
||||||
|
├── backup/ # Backups zip (non versionne)
|
||||||
|
├── logs/ # Logs de backup (non versionne)
|
||||||
└── README.md
|
└── README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
57
backup-vaultwarden.sh
Executable file
57
backup-vaultwarden.sh
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DATA_DIR="/home/matt/vaultwarden/data"
|
||||||
|
BACKUP_DIR="/home/matt/vaultwarden/backup"
|
||||||
|
RETENTION=2
|
||||||
|
WEBHOOK_URL="https://discord.com/api/webhooks/1478503102888935506/YCtJM09QZiKNMiCe5u7vCQb52VcLjHAd9wwEsKNltlJVcy7sKvoMTOJkvEKOOrk-Wpkh"
|
||||||
|
LOG_FILE="/home/matt/vaultwarden/logs/vaultwarden_backup.log"
|
||||||
|
|
||||||
|
DATE="$(date +'%Y-%m-%d_%H-%M-%S')"
|
||||||
|
BACKUP_NAME="vaultwarden-backup-${DATE}.zip"
|
||||||
|
BACKUP_FILE="${BACKUP_DIR}/${BACKUP_NAME}"
|
||||||
|
|
||||||
|
mkdir -p "$BACKUP_DIR" "$(dirname "$LOG_FILE")"
|
||||||
|
|
||||||
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; }
|
||||||
|
|
||||||
|
discord() {
|
||||||
|
local color="$1" title="$2" msg="$3"
|
||||||
|
[[ -z "$WEBHOOK_URL" ]] && return 0
|
||||||
|
curl -fsS -H "Content-Type: application/json" -d "{
|
||||||
|
\"embeds\": [{
|
||||||
|
\"title\": \"${title}\",
|
||||||
|
\"description\": \"${msg}\",
|
||||||
|
\"color\": ${color}
|
||||||
|
}]
|
||||||
|
}" "$WEBHOOK_URL" >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
log "ERROR: $1"
|
||||||
|
discord 16711680 "Backup Vaultwarden - ECHEC" "$1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verifications
|
||||||
|
[[ -d "$DATA_DIR" ]] || fail "Dossier source introuvable : $DATA_DIR"
|
||||||
|
command -v zip &>/dev/null || fail "zip n'est pas installe"
|
||||||
|
|
||||||
|
log "Debut backup - source: $DATA_DIR"
|
||||||
|
|
||||||
|
# Zip du dossier data
|
||||||
|
cd "$(dirname "$DATA_DIR")"
|
||||||
|
zip -r -q "$BACKUP_FILE" "$(basename "$DATA_DIR")" || fail "Erreur lors de la compression"
|
||||||
|
|
||||||
|
SIZE="$(du -h "$BACKUP_FILE" | cut -f1)"
|
||||||
|
log "Backup cree : $BACKUP_FILE ($SIZE)"
|
||||||
|
|
||||||
|
# Rotation - garde les 2 derniers
|
||||||
|
mapfile -t old < <(ls -1t "${BACKUP_DIR}"/vaultwarden-backup-*.zip 2>/dev/null | tail -n +$((RETENTION + 1)))
|
||||||
|
for f in "${old[@]}"; do
|
||||||
|
rm -f "$f"
|
||||||
|
log "Rotation : supprime $f"
|
||||||
|
done
|
||||||
|
|
||||||
|
log "Backup termine : $BACKUP_NAME"
|
||||||
|
discord 65280 "Backup Vaultwarden - OK" "Backup **${BACKUP_NAME}** cree (${SIZE})"
|
||||||
Reference in New Issue
Block a user