Added vaultwarden script documentation
This commit is contained in:
1 parent
f62d60802f
commit
e852924fb4
1 file changed
+220
@@ -0,0 +1,220 @@
|
||||
# Vaultwarden Backup & Restore Guide
|
||||
|
||||
> [!Note]
|
||||
> The official backup and restore documentation for Vaultwarden is located on the [Vaultwarden GitHub Wiki](https://github.com/dani-garcia/vaultwarden/wiki/Backing-up-your-vault). The steps below are tailored specifically to our local Docker container setup and automated backup script.
|
||||
|
||||
---
|
||||
|
||||
# Script Architecture & Workflow
|
||||
|
||||
The custom backup script (`vaultwarden_backup.sh`) automates point-in-time snapshots of Vaultwarden while maintaining database integrity, supporting non-POSIX external backup drives (exFAT/NTFS), and providing real-time notification alerts.
|
||||
|
||||
```
|
||||
+-------------------------------------------------------+
|
||||
| Pre-flight Checks |
|
||||
| (Mount point verify -> Data Dir check -> Docker running)
|
||||
+---------------------------+---------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------------------------------+
|
||||
| Step 1: Container DB Snapshot |
|
||||
| `docker exec vaultwarden /vaultwarden backup` |
|
||||
| (Generates db_YYYYMMDD_HHMMSS.sqlite3 safely in WAL) |
|
||||
+---------------------------+---------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------------------------------+
|
||||
| Step 2: Sync Snapshot DB |
|
||||
| `rsync` snapshot -> `CURRENT_BACKUP_DIR/db.sqlite3` |
|
||||
| (Deletes local temp snapshot file) |
|
||||
+---------------------------+---------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------------------------------+
|
||||
| Step 3: Sync Attachments & Data |
|
||||
| `rsync` attachments, sends, RSA keys, config |
|
||||
| (Excludes active live `db.sqlite3*`) |
|
||||
+---------------------------+---------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------------------------------+
|
||||
| Step 4: Update Path Pointer |
|
||||
| Write `CURRENT_BACKUP_DIR` path -> `latest.txt` |
|
||||
+---------------------------+---------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------------------------------+
|
||||
| Step 5: Retention Cleanup |
|
||||
| `find` & delete `backup_*` folders > 30 days |
|
||||
+---------------------------+---------------------------+
|
||||
|
|
||||
v
|
||||
+-------------------------------------------------------+
|
||||
| ntfy Status Alert Sent |
|
||||
+-------------------------------------------------------+
|
||||
```
|
||||
|
||||
## Detailed Breakdown of Script Operations
|
||||
|
||||
### 1. Pre-flight Infrastructure Checks
|
||||
Before modifying any data or making temporary local files, the script verifies three critical dependencies:
|
||||
* **Mount Verification (`mountpoint -q`)**: Ensures `/mnt/5TB-Disk1` is an actively mounted filesystem. This prevents writing gigabytes of backup data to the local host root disk if the external drive gets disconnected.
|
||||
* **Source Path Verification**: Confirms `/srv/docker/vaultwarden/data` exists.
|
||||
* **Container State Check**: Verifies that the Vaultwarden Docker container is actively running using `docker ps`.
|
||||
|
||||
If any pre-flight test fails, the script sends an error payload to `ntfy` and exits immediately with status code `1`.
|
||||
|
||||
### 2. Database Snapshot Generation (Hot Backup)
|
||||
Vaultwarden uses SQLite with Write-Ahead Logging (WAL). Directly copying `db.sqlite3` with standard filesystem tools (`cp`, `rsync`) while Vaultwarden is writing will produce a **corrupted database backup**.
|
||||
|
||||
To prevent corruption, the script invokes Vaultwarden's native backup CLI command inside the container:
|
||||
```bash
|
||||
docker exec vaultwarden /vaultwarden backup
|
||||
```
|
||||
* **How it works**: Vaultwarden issues an online SQLite backup API call that safely locks transactions briefly, creates a complete, uncorrupted database copy named `db_YYYYMMDD_HHMMSS.sqlite3` inside the host volume directory (`/srv/docker/vaultwarden/data`), and immediately releases the lock.
|
||||
|
||||
### 3. Isolated Target Snapshot & Normalization
|
||||
Once generated, the script locates the newest `db_*.sqlite3` snapshot and copies it to the target backup folder as `db.sqlite3`:
|
||||
* **Naming Standardization**: Renaming `db_YYYYMMDD_HHMMSS.sqlite3` to `db.sqlite3` at the destination creates a turnkey restoration layout matching Vaultwarden's default expectation.
|
||||
* **Local Cleanup**: Immediately after copying, `rm -f "$LATEST_DB_BACKUP"` removes the temporary snapshot from host storage (`/srv/docker/vaultwarden/data/`) to prevent local disk exhaustion.
|
||||
|
||||
### 4. Asset Synchronization (`rsync`)
|
||||
Attachments, user sends, encryption keys (`rsa_key*`), and server configurations (`config.json`) are synced using `rsync`:
|
||||
```bash
|
||||
rsync -av --no-owner --no-group --exclude='db.sqlite3*' /srv/docker/vaultwarden/data/ "$CURRENT_BACKUP_DIR/"
|
||||
```
|
||||
* **Flag Explanation**:
|
||||
* `-a` (Archive mode): Preserves modification times, recursive directory structure, and file permissions.
|
||||
* `--no-owner --no-group`: Prevents `rsync` from throwing permission warnings when backing up to filesystems (like exFAT or NTFS) that do not support POSIX user/group ownership mapping.
|
||||
* `--exclude='db.sqlite3*'`: Prevents active WAL journal files (`db.sqlite3-wal`, `db.sqlite3-shm`) from being copied alongside the static `db.sqlite3` snapshot.
|
||||
|
||||
### 5. Filesystem-Agnostic "Latest" Pointer
|
||||
On standard Linux filesystems (ext4/btrfs), scripts usually create a symbolic link (`ln -s`) to mark the latest backup folder. However, drives formatted as **exFAT, FAT32, or NTFS** reject symlinks with `Operation not permitted`.
|
||||
|
||||
To keep the script 100% compatible with any storage medium:
|
||||
* The script writes the absolute path of the newest backup folder into a plain text file: `/mnt/5TB-Disk1/backup/services/vaultwarden/latest.txt`.
|
||||
* Restores or external monitoring scripts can simply read `cat latest.txt` to discover the active backup location.
|
||||
|
||||
### 6. Retention Engine
|
||||
Automatic backup rotation is performed using `find`:
|
||||
```bash
|
||||
find "$VAULTWARDEN_DESTINATION" -maxdepth 1 -type d -name "backup_*" -mtime +30 -exec rm -rf {} +
|
||||
```
|
||||
* `-maxdepth 1`: Restricts search depth to the top-level Vaultwarden backup directory to avoid recursing into subdirectories.
|
||||
* `-name "backup_*"`: Filters strictly for directories generated by this script.
|
||||
* `-mtime +30`: Identifies folders whose file modification time is strictly older than 30 days (720 hours).
|
||||
* `-exec rm -rf {} +`: Deletes matching historical backup directories in a single batch operation.
|
||||
|
||||
### 7. Event Notifications via ntfy
|
||||
All execution pathways (successes, container missing, unmounted drives, `rsync` failures) trigger an HTTP `POST` request to the defined `ntfy` server via `curl`, delivering real-time status updates directly to connected clients.
|
||||
|
||||
---
|
||||
|
||||
# Automated Backup Execution
|
||||
|
||||
## Cron Configuration
|
||||
|
||||
The backup script is executed automatically via root's crontab.
|
||||
|
||||
To view or edit the automated schedule:
|
||||
```bash
|
||||
sudo crontab -e
|
||||
```
|
||||
|
||||
**Recommended Schedule (Every night at 2:30 AM):**
|
||||
```cron
|
||||
30 2 * * * /bin/bash /srv/docker/vaultwarden/vaultwarden_backup.sh >/dev/null 2>&1
|
||||
```
|
||||
|
||||
## Manual Script Execution
|
||||
|
||||
To manually trigger a complete backup at any time:
|
||||
```bash
|
||||
sudo /srv/docker/vaultwarden/vaultwarden_backup.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Manual Backup Procedure
|
||||
|
||||
If you need to perform a backup manually without using the script:
|
||||
|
||||
### 1. Generate Container Database Snapshot
|
||||
```bash
|
||||
sudo docker exec vaultwarden /vaultwarden backup
|
||||
```
|
||||
|
||||
### 2. Copy Snapshot and Assets
|
||||
```bash
|
||||
# Define target directory
|
||||
TARGET_DIR="/mnt/5TB-Disk1/backup/services/vaultwarden/manual_$(date +%Y-%m-%d_%H%M%S)"
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
# Locate and copy the generated DB snapshot
|
||||
LATEST_DB=$(ls -t /srv/docker/vaultwarden/data/db_*.sqlite3 | head -n 1)
|
||||
sudo rsync -av --no-owner --no-group "$LATEST_DB" "$TARGET_DIR/db.sqlite3"
|
||||
|
||||
# Remove the temporary snapshot from source
|
||||
sudo rm -f "$LATEST_DB"
|
||||
|
||||
# Copy remaining assets (RSA keys, attachments, sends, config)
|
||||
sudo rsync -av --no-owner --no-group --exclude='db.sqlite3*' /srv/docker/vaultwarden/data/ "$TARGET_DIR/"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Restore Vaultwarden Procedure
|
||||
|
||||
> [!Caution]
|
||||
> Always stop the Vaultwarden container before restoring files. Overwriting files on an active container can cause database locks or file corruption.
|
||||
|
||||
### Step 1: Identify Backup to Restore
|
||||
Identify the backup directory path from `latest.txt` or list all available timestamped backups:
|
||||
|
||||
```bash
|
||||
# View path to the most recent successful backup
|
||||
cat /mnt/5TB-Disk1/backup/services/vaultwarden/latest.txt
|
||||
|
||||
# Or list all historical backup directories
|
||||
ls -l /mnt/5TB-Disk1/backup/services/vaultwarden/
|
||||
```
|
||||
|
||||
### Step 2: Stop Vaultwarden Container
|
||||
```bash
|
||||
sudo docker stop vaultwarden
|
||||
# OR if using Docker Compose:
|
||||
# cd /srv/docker/vaultwarden && sudo docker compose down
|
||||
```
|
||||
|
||||
### Step 3: Restore Data Files
|
||||
Rsync the database snapshot, attachments, sends, and RSA keys back to the host data directory.
|
||||
|
||||
> [!Note]
|
||||
> Replace `/mnt/5TB-Disk1/backup/services/vaultwarden/backup_YYYY-MM-DD_HHMMSS` below with the target backup directory you wish to restore.
|
||||
|
||||
```bash
|
||||
sudo rsync -av --delete /mnt/5TB-Disk1/backup/services/vaultwarden/backup_2026-10-03_101124/ /srv/docker/vaultwarden/data/
|
||||
```
|
||||
|
||||
### Step 4: Verify Host File Permissions
|
||||
Ensure the restored files match the container user's expected ownership (UID/GID `1000:1000` default):
|
||||
|
||||
```bash
|
||||
sudo chown -R 1000:1000 /srv/docker/vaultwarden/data
|
||||
```
|
||||
|
||||
### Step 5: Start Vaultwarden Container & Verify Logs
|
||||
```bash
|
||||
sudo docker start vaultwarden
|
||||
# OR if using Docker Compose:
|
||||
# cd /srv/docker/vaultwarden && sudo docker compose up -d
|
||||
|
||||
# Verify startup logs
|
||||
sudo docker logs -f vaultwarden
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Authors and Acknowledgment
|
||||
* **Vaultwarden Wiki**: https://github.com/dani-garcia/vaultwarden/wiki
|
||||
* **Vaultwarden Repository**: https://github.com/dani-garcia/vaultwarden
|
||||
Reference in new issue
Block a user