Table of Contents
- Backup y Restauración
- 🔴 Por Qué son Críticos los Backups
- 📦 Qué Respaldar
- 🛠️ Métodos de Backup
- Método 1: Backup Manual Completo (Recomendado)
- Método 2: Backup sin Detener el Servicio
- Método 3: Backup Automatizado con Cron
- Método 4: Docker Volume Backup (Contenedor Dedicado)
- 💾 Dónde Almacenar Backups
- 🔄 Restauración
- ✅ Verificar Backups
- 📊 Monitorización de Backups
- 🔐 Cifrar Backups
- 📖 Checklist de Backup
- 🆘 Escenarios de Desastre
Backup y Restauración
⚠️ CRÍTICO: Vaultwarden almacena todas tus contraseñas. Sin backup, puedes perderlo todo. Esta es la página más importante de la wiki.
🔴 Por Qué son Críticos los Backups
Un gestor de contraseñas sin backup es una bomba de tiempo:
- 💥 Fallo de hardware: Disco duro que muere
- 🔥 Corrupción de datos: Error del sistema de archivos
- 🚫 Actualización fallida: Docker o Vaultwarden se rompe
- 🏢 Migración de servidor: Necesitas moverte a otro host
- 👤 Error humano:
docker compose down -vpor accidente
Un solo comando sin backup puede borrar años de contraseñas.
📦 Qué Respaldar
Vaultwarden almacena todo en el volumen Docker vaultwarden_data:
vaultwarden_data/
├── db.sqlite3 # Base de datos (contraseñas, usuarios)
├── db.sqlite3-wal # Write-Ahead Log (transacciones)
├── db.sqlite3-shm # Shared memory
├── attachments/ # Archivos adjuntos
├── sends/ # Sends temporales
├── config.json # Configuración del servidor
├── rsa_key.pem # Clave privada RSA
├── rsa_key.pub.pem # Clave pública RSA
└── vaultwarden.log # Logs (opcional)
Archivos críticos:
- ✅
db.sqlite3*- Base de datos completa - ✅
rsa_key*.pem- Claves de cifrado - ✅
config.json- Configuración - ✅
attachments/- Adjuntos de los usuarios
Opcionales:
vaultwarden.log- Solo para debuggingsends/- Normalmente vacío (envíos temporales)
🛠️ Métodos de Backup
Método 1: Backup Manual Completo (Recomendado)
Copia todo el volumen Docker.
#!/bin/bash
# Script: backup-vaultwarden.sh
# Configuración
BACKUP_DIR="$HOME/backups/vaultwarden"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="vaultwarden-backup-${TIMESTAMP}.tar.gz"
# Crear directorio si no existe
mkdir -p "$BACKUP_DIR"
# Detener el contenedor (para consistencia)
docker compose -f /ruta/a/vaultwarden/docker-compose.yml stop vaultwarden
# Crear backup del volumen
docker run --rm \
-v vaultwarden_data:/data \
-v "$BACKUP_DIR":/backup \
alpine \
tar czf "/backup/$BACKUP_FILE" -C /data .
# Reiniciar el contenedor
docker compose -f /ruta/a/vaultwarden/docker-compose.yml start vaultwarden
# Verificar backup
if [ -f "$BACKUP_DIR/$BACKUP_FILE" ]; then
echo "✅ Backup creado: $BACKUP_FILE"
ls -lh "$BACKUP_DIR/$BACKUP_FILE"
else
echo "❌ ERROR: Backup falló"
exit 1
fi
# Limpieza: Mantener solo últimos 30 backups
cd "$BACKUP_DIR"
ls -t vaultwarden-backup-*.tar.gz | tail -n +31 | xargs -r rm
echo "✅ Backup completado correctamente"
Método 2: Backup sin Detener el Servicio
Si tu instancia es 24/7 crítica:
#!/bin/bash
# Backup en caliente con SQLite checkpoint
BACKUP_DIR="$HOME/backups/vaultwarden"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="vaultwarden-backup-${TIMESTAMP}.tar.gz"
mkdir -p "$BACKUP_DIR"
# Forzar checkpoint de SQLite (fusiona WAL)
docker compose exec vaultwarden sqlite3 /data/db.sqlite3 "PRAGMA wal_checkpoint(TRUNCATE);"
# Backup sin detener
docker run --rm \
-v vaultwarden_data:/data:ro \
-v "$BACKUP_DIR":/backup \
alpine \
tar czf "/backup/$BACKUP_FILE" -C /data .
echo "✅ Backup en caliente completado: $BACKUP_FILE"
⚠️ Advertencia: Los backups en caliente pueden capturar estados inconsistentes. Para máxima seguridad, usa el Método 1.
Método 3: Backup Automatizado con Cron
Automatiza backups diarios a las 3 AM:
# Editar crontab
crontab -e
# Añadir esta línea
0 3 * * * /home/usuario/scripts/backup-vaultwarden.sh >> /var/log/vaultwarden-backup.log 2>&1
Verifica que funciona:
# Ver logs del cron
tail -f /var/log/vaultwarden-backup.log
# Probar el script manualmente
bash /home/usuario/scripts/backup-vaultwarden.sh
Método 4: Docker Volume Backup (Contenedor Dedicado)
Usa un contenedor especializado para backups automáticos:
services:
# ... tu servicio vaultwarden ...
backup:
image: offen/docker-volume-backup:latest
restart: unless-stopped
environment:
BACKUP_CRON_EXPRESSION: "0 3 * * *" # Diario a las 3 AM
BACKUP_FILENAME: "vaultwarden-backup-%Y%m%d-%H%M%S.tar.gz"
BACKUP_RETENTION_DAYS: 30
BACKUP_PRUNING_PREFIX: "vaultwarden-backup-"
volumes:
- vaultwarden_data:/backup/vaultwarden_data:ro
- /ruta/backups:/archive
Ventajas:
- ✅ Completamente automático
- ✅ Rotación de backups integrada
- ✅ Notificaciones opcionales (webhook, email)
💾 Dónde Almacenar Backups
⚠️ NO Almacenar SOLO en el Mismo Servidor
Si el servidor muere, pierdes datos Y backups.
✅ Estrategia 3-2-1
- 3 copias de tus datos
- 2 medios diferentes
- 1 copia offsite (fuera del servidor)
Opciones de Almacenamiento
1. NAS Local
# Montar NAS
mount -t nfs nas.local:/backups /mnt/nas
# Modificar script de backup
BACKUP_DIR="/mnt/nas/vaultwarden"
2. Cloud Storage (S3, B2, etc.)
# Instalar rclone
curl https://rclone.org/install.sh | sudo bash
# Configurar remote
rclone config
# Sincronizar backups
rclone sync $HOME/backups/vaultwarden remote:vaultwarden-backups
3. Servidor Remoto (SCP/Rsync)
# Después del backup, envía a servidor remoto
scp "$BACKUP_DIR/$BACKUP_FILE" usuario@servidor-backup:/backups/vaultwarden/
# O con rsync
rsync -avz "$BACKUP_DIR/" usuario@servidor-backup:/backups/vaultwarden/
4. Duplicati (GUI)
Duplicati ofrece backups cifrados y automáticos:
services:
duplicati:
image: duplicati/duplicati
ports:
- "8200:8200"
environment:
TZ: Europe/Madrid
volumes:
- vaultwarden_data:/source/vaultwarden:ro
- duplicati_config:/data
Configura desde http://servidor:8200
🔄 Restauración
Restauración Completa
Recupera todo el volumen desde un backup:
#!/bin/bash
# Script: restore-vaultwarden.sh
BACKUP_FILE="/ruta/al/backup/vaultwarden-backup-20240101_030000.tar.gz"
# Verificar que el backup existe
if [ ! -f "$BACKUP_FILE" ]; then
echo "❌ ERROR: Backup no encontrado: $BACKUP_FILE"
exit 1
fi
# Detener Vaultwarden
docker compose stop vaultwarden
# ADVERTENCIA: Esto borra los datos actuales
read -p "⚠️ Esto BORRARÁ los datos actuales. ¿Continuar? (yes/no): " -r
if [[ ! $REPLY =~ ^yes$ ]]; then
echo "❌ Restauración cancelada"
exit 1
fi
# Restaurar backup
docker run --rm \
-v vaultwarden_data:/data \
-v "$(dirname $BACKUP_FILE)":/backup \
alpine \
sh -c "cd /data && rm -rf * && tar xzf /backup/$(basename $BACKUP_FILE)"
# Reiniciar Vaultwarden
docker compose start vaultwarden
echo "✅ Restauración completada"
echo "Verifica que puedes acceder: https://vaultwarden.tudominio.com"
Restauración desde Cero
Si estás migrando a un servidor nuevo:
# 1. Instalar Docker y Docker Compose
# 2. Clonar repositorio
git clone https://git.ictiberia.com/groales/vaultwarden.git
cd vaultwarden
# 3. Configurar override y .env
cp docker-compose.override.traefik.yml.example docker-compose.override.yml
nano .env # Configurar variables
# 4. Crear volumen vacío
docker volume create vaultwarden_data
# 5. Restaurar datos desde backup
docker run --rm \
-v vaultwarden_data:/data \
-v /ruta/al/backup:/backup \
alpine \
tar xzf /backup/vaultwarden-backup-YYYYMMDD.tar.gz -C /data
# 6. Iniciar Vaultwarden
docker compose up -d
# 7. Verificar
docker compose logs -f vaultwarden
Restauración Selectiva (Solo DB)
Si solo necesitas la base de datos:
# Extraer solo db.sqlite3 del backup
tar xzf vaultwarden-backup-20240101.tar.gz db.sqlite3
# Copiar al volumen
docker cp db.sqlite3 vaultwarden:/data/db.sqlite3
# Reiniciar
docker compose restart vaultwarden
✅ Verificar Backups
Probar Restauración
Una vez al mes, prueba restaurar un backup en un entorno de testing:
# Crear volumen temporal
docker volume create vaultwarden_test
# Restaurar backup en volumen test
docker run --rm \
-v vaultwarden_test:/data \
-v /ruta/backups:/backup \
alpine \
tar xzf /backup/vaultwarden-backup-YYYYMMDD.tar.gz -C /data
# Levantar Vaultwarden test
docker run -d --name vaultwarden-test \
-v vaultwarden_test:/data \
-p 8081:80 \
vaultwarden/server:latest
# Probar acceso
curl http://localhost:8081
# Limpiar
docker stop vaultwarden-test
docker rm vaultwarden-test
docker volume rm vaultwarden_test
Verificar Integridad de SQLite
# Verificar que la DB no está corrupta
docker run --rm \
-v vaultwarden_data:/data:ro \
nouchka/sqlite3 \
sqlite3 /data/db.sqlite3 "PRAGMA integrity_check;"
Debería devolver: ok
Listar Backups Disponibles
# Ver backups y sus tamaños
ls -lh $HOME/backups/vaultwarden/
# Ver el más reciente
ls -lt $HOME/backups/vaultwarden/ | head -n 2
# Verificar que no están vacíos
find $HOME/backups/vaultwarden/ -type f -size 0
📊 Monitorización de Backups
Script de Verificación Diaria
#!/bin/bash
# verify-backup.sh
BACKUP_DIR="$HOME/backups/vaultwarden"
MAX_AGE_HOURS=30 # Alerta si el último backup tiene más de 30 horas
LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/vaultwarden-backup-*.tar.gz | head -n 1)
if [ -z "$LATEST_BACKUP" ]; then
echo "❌ ERROR: No se encontraron backups"
exit 1
fi
# Verificar edad
BACKUP_AGE=$(( ($(date +%s) - $(stat -c %Y "$LATEST_BACKUP")) / 3600 ))
if [ $BACKUP_AGE -gt $MAX_AGE_HOURS ]; then
echo "⚠️ ADVERTENCIA: Último backup tiene ${BACKUP_AGE} horas"
echo "Backup: $LATEST_BACKUP"
exit 1
else
echo "✅ Backup reciente: ${BACKUP_AGE} horas"
echo "Backup: $LATEST_BACKUP"
fi
Notificaciones (Opcional)
Envía alertas si los backups fallan:
# Al final del script de backup
if [ $? -eq 0 ]; then
curl -X POST https://hooks.slack.com/services/TU_WEBHOOK \
-d '{"text":"✅ Backup de Vaultwarden completado"}'
else
curl -X POST https://hooks.slack.com/services/TU_WEBHOOK \
-d '{"text":"❌ ERROR en backup de Vaultwarden"}'
fi
🔐 Cifrar Backups
Los backups contienen todas las contraseñas. Cífralos para almacenamiento externo:
Con GPG
# Backup y cifrado
tar czf - -C /var/lib/docker/volumes/vaultwarden_data/_data . | \
gpg --symmetric --cipher-algo AES256 > vaultwarden-backup.tar.gz.gpg
# Descifrado
gpg --decrypt vaultwarden-backup.tar.gz.gpg | tar xzf -
Con OpenSSL
# Cifrar
openssl enc -aes-256-cbc -salt \
-in vaultwarden-backup.tar.gz \
-out vaultwarden-backup.tar.gz.enc
# Descifrar
openssl enc -aes-256-cbc -d \
-in vaultwarden-backup.tar.gz.enc \
-out vaultwarden-backup.tar.gz
📖 Checklist de Backup
- Backups automáticos configurados (diarios mínimo)
- Backups almacenados en al menos 2 ubicaciones
- Al menos 1 backup offsite (fuera del servidor)
- Backups cifrados si se almacenan en cloud
- Script de restauración probado al menos una vez
- Monitorización de backups (verificar que se ejecutan)
- Rotación de backups (no llenar el disco)
- Documentación de cómo restaurar
🆘 Escenarios de Desastre
Servidor Completamente Muerto
- Montar nuevo servidor
- Instalar Docker
- Clonar repo de Vaultwarden
- Configurar variables de entorno
- Restaurar backup en volumen nuevo
- Iniciar stack
- Actualizar DNS si cambió la IP
Base de Datos Corrupta
- Detener Vaultwarden
- Renombrar db corrupta:
mv db.sqlite3 db.sqlite3.corrupted - Restaurar desde backup más reciente
- Verificar integridad:
sqlite3 db.sqlite3 "PRAGMA integrity_check;" - Reiniciar Vaultwarden
Volumen Docker Borrado Accidentalmente
# Recrear volumen
docker volume create vaultwarden_data
# Restaurar inmediatamente desde backup
bash restore-vaultwarden.sh
Última actualización: Diciembre 2025
⚠️ RECUERDA: Un backup de 6 meses vale más que 10 veces lo que cuesta hacerlo. Automatiza ahora.