Saltar a contenido

Backup Restore Strategy

Objetivo

Mantener la certificacion DR en VERDE con backup recurrente diario, retencion clara y evidencia exportable fuera del VPS sin tocar el runtime productivo.

Restricciones respetadas

  • SAFE POINT inicial tomado
  • sin tocar DNS
  • sin tocar firewall
  • sin tocar NPM operativo
  • sin borrar OpenClaw productivo
  • sin detener produccion

Safe Point Inicial

  • Fecha local: 2026-05-31
  • Commit base: 6445ca4e989d3ac287ce658ec4badf96ac006476
  • git status --short inicial: limpio
  • Host remoto: srv977009
  • Contenedores activos:
  • openclaw-openclaw-gateway-1
  • nginx-proxy-manager
  • portainer

Fase 1 - Inventario exacto de reconstruccion

Activo Ruta real Tamano Critico Metodo de restore
OpenClaw compose /opt/stacks/openclaw/docker-compose.yml 3356 B si restaurar archivo versionado o extraer desde openclaw-stack.tgz
OpenClaw env /opt/stacks/openclaw/.env 969 B si restaurar archivo desde backup al mismo path con permisos 600
OpenClaw config /opt/stacks/openclaw/config 715937 B si extraer backup al mismo path y conservar owner operativo
OpenClaw workspace /opt/stacks/openclaw/workspace 37562 B si extraer backup al mismo path
OpenClaw auth-profile-secrets /opt/stacks/openclaw/auth-profile-secrets 0 B medio recrear directorio vacio; no contiene la auth efectiva observada
NPM compose /docker/nginx-proxy-manager/docker-compose.yml 510 B si restaurar archivo y recrear stack
NPM data /docker/nginx-proxy-manager/data 1149405 B si restaurar arbol completo; incluye database.sqlite, keys.json, nginx/proxy_host/*.conf y logs
NPM certificados SSL /docker/nginx-proxy-manager/letsencrypt 46827 B si restaurar arbol completo antes de levantar NPM
NPM Proxy Hosts /docker/nginx-proxy-manager/data/nginx/proxy_host/*.conf dentro de data si queda cubierto por backup de data; archivos observados 2.conf y 3.conf
Portainer volumen activo /var/lib/docker/volumes/portainer_data_new/_data 527043 B si extraer backup sobre un volumen nuevo o restaurado y recrear contenedor
Portainer config metadata /var/lib/docker/volumes/portainer_data_new/_data/compose dentro de volumen si queda cubierta por backup del volumen; se observaron compose/1/docker-compose.yml y compose/2/docker-compose.yml
Backup VPS proveedor Hostinger + reprovision manual del host externo si snapshot si existe; si no, reprovision Ubuntu + Docker + restore de NPM/OpenClaw/Portainer

Fase 2 - Estrategia de backup restaurable y automatizable

OpenClaw

  • Fuente:
  • /opt/stacks/openclaw/docker-compose.yml
  • /opt/stacks/openclaw/.env
  • /opt/stacks/openclaw/config
  • /opt/stacks/openclaw/workspace
  • /opt/stacks/openclaw/auth-profile-secrets
  • Tratamiento:
  • copia de archivos y directorios a staging
  • backup logico de SQLite para:
    • config/flows/registry.sqlite
    • config/memory/main.sqlite
    • config/tasks/runs.sqlite
  • eliminacion de *.sqlite-wal y *.sqlite-shm en el snapshot
  • Salida:
  • openclaw-stack.tgz

NPM

  • Fuente:
  • /docker/nginx-proxy-manager/docker-compose.yml
  • /docker/nginx-proxy-manager/data
  • /docker/nginx-proxy-manager/letsencrypt
  • Tratamiento:
  • copia a staging
  • backup logico de SQLite para /docker/nginx-proxy-manager/data/database.sqlite
  • Salida:
  • npm-stack.tgz

Portainer

  • Fuente:
  • volumen portainer_data_new
  • mountpoint: /var/lib/docker/volumes/portainer_data_new/_data
  • Tratamiento:
  • copia byte a byte del volumen a staging
  • portainer.db se conserva como archivo binario porque el host lo reporta como data, no como SQLite legible
  • Salida:
  • portainer-volume.tgz

VPS

  • Cobertura real conseguida en esta etapa:
  • reconstruccion documentada del host sin depender de Git para secretos
  • backup de componentes aplicacionales y administrativos criticos
  • Cobertura externa:
  • snapshot del proveedor si esta disponible
  • Si no hay snapshot:
  • reprovision Ubuntu 24.04
  • instalar Docker y Compose
  • recrear proxy-network
  • restaurar NPM
  • restaurar OpenClaw
  • restaurar Portainer

Fase 3 - Procedimiento operativo

Backup

  1. Verificar SAFE POINT: git status -sb y git rev-parse HEAD
  2. Ejecutar: powershell -ExecutionPolicy Bypass -File scripts/dr/Invoke-DrBackupRestoreEvidence.ps1 -HostAlias openclaw-vps
  3. Conservar:
  4. ruta BASE=/tmp/dr-green-<timestamp>
  5. sha256sum de cada .tgz
  6. stdout completo como evidencia

Backup recurrente diario

  • Script VPS:
  • scripts/backup/openclaw-vps-backup.sh
  • Ruta instalada en VPS:
  • /root/openclaw-backups/bin/openclaw-vps-backup.sh
  • Frecuencia:
  • diaria 03:00 por crontab
  • Retencion:
  • diarios: 30 dias
  • semanales: 12 copias si la corrida ocurre en domingo
  • logs: 90 dias
  • Rutas de salida:
  • diarios: /root/openclaw-backups/daily/<timestamp>
  • semanales: /root/openclaw-backups/weekly/<YYYY-weekWW>
  • logs: /root/openclaw-backups/logs/openclaw-backup-<timestamp>.log
  • Artefactos por corrida:
  • openclaw-stack.tgz
  • npm-stack.tgz
  • portainer-volume.tgz
  • SHA256SUMS
  • manifest.txt
  • Seguridad aplicada:
  • umask 077
  • directorios 700
  • archivos 600
  • sin impresion de secretos en stdout ni en logs

Copia externa de evidencia

  • Script Windows:
  • scripts/backup/pull-openclaw-backups-to-windows.ps1
  • Ruta local preparada:
  • C:\APV\backups\openclaw\
  • Comportamiento:
  • resuelve el backup remoto mas nuevo o uno puntual
  • copia por scp
  • valida SHA256SUMS
  • deja log local en C:\APV\backups\openclaw\logs\
  • Automatizacion:
  • no instalada todavia
  • Task Scheduler queda como paso opcional posterior a validar almacenamiento, permisos y capacidad local

Verificacion de cron

  • Script de instalacion:
  • scripts/backup/install-vps-cron.sh
  • Entrada instalada:
  • 0 3 * * * /root/openclaw-backups/bin/openclaw-vps-backup.sh >/dev/null 2>&1
  • Verificar:
  • crontab -l
  • crontab -l | grep -F 'openclaw-recurring-backup'
  • No duplica entradas existentes.

Validacion

  1. Confirmar que el script crea:
  2. openclaw-stack.tgz
  3. npm-stack.tgz
  4. portainer-volume.tgz
  5. Confirmar extraccion de prueba en:
  6. restore/openclaw
  7. restore/npm
  8. restore/portainer
  9. Validar contenido minimo:
  10. OpenClaw: .env, docker-compose.yml, config/openclaw.json, config/agents/main/agent/auth-profiles.json
  11. NPM: data/database.sqlite, data/nginx/proxy_host/*.conf, letsencrypt/live/
  12. Portainer: compose/*/docker-compose.yml, portainer.db

Restauracion

  1. Preparar VPS base o staging host con Docker y Compose.
  2. Restaurar NPM primero:
  3. extraer npm-stack.tgz en /docker/nginx-proxy-manager
  4. cd /docker/nginx-proxy-manager && docker compose up -d
  5. Restaurar OpenClaw despues:
  6. extraer openclaw-stack.tgz en /opt/stacks/openclaw
  7. recrear proxy-network si falta: docker network create proxy-network
  8. cd /opt/stacks/openclaw && docker compose up -d
  9. Restaurar Portainer al final:
  10. crear volumen nuevo o reutilizar portainer_data_new
  11. extraer portainer-volume.tgz dentro del mountpoint del volumen
  12. recrear contenedor portainer con mismo docker.sock, puertos y red
  13. Smoke tests obligatorios:
  14. docker ps
  15. docker inspect -f '{{.State.Health.Status}}' openclaw-openclaw-gateway-1
  16. curl -I https://openclaw.alpuntodeventa.com.ar/
  17. curl -k -I https://127.0.0.1:9443
  18. curl -I http://127.0.0.1:81

Fase 4 - Persistencia exacta de auth OpenAI

  • El bind mount auth-profile-secrets/ no guarda la auth efectiva en este despliegue.
  • Los archivos observados que si persisten auth y estado del agente son:
  • /opt/stacks/openclaw/config/agents/main/agent/auth-profiles.json
    • profiles: openai:default
  • /opt/stacks/openclaw/config/agents/main/agent/auth-state.json
    • lastGood: openai
    • usageStats: openai:default
  • /opt/stacks/openclaw/config/identity/device-auth.json
    • tokens: operator
  • Mecanismo:
  • el contenedor monta ./config:/home/node/.openclaw
  • esos archivos viven en el filesystem del host
  • por eso sobreviven a reinicios y recreacion del contenedor

Fase 5 - Simulacion controlada no destructiva

  • Ejecucion evidenciada:
  • staging y backups en /tmp/dr-green-20260531-011407
  • Checksums reales:
  • openclaw-stack.tgz f2a659b9a4564b2561779d39842b46c83a439e76f389a9c1580313a3d7e9d20f
  • npm-stack.tgz cf64d4a8bef17a6f8c4c3ea8637e951c0b69abab91cd9461e35f16de10852c43
  • portainer-volume.tgz fd8c9385307ee27c5525c8089baee94aa1eae68e4d8968ac5a212cf8e75c2a32
  • Restore no destructivo validado por extraccion de:
  • OpenClaw:
    • config/flows/registry.sqlite
    • config/memory/main.sqlite
    • config/tasks/runs.sqlite
  • NPM:
    • data/nginx/proxy_host/2.conf
    • data/nginx/proxy_host/3.conf
  • Portainer:
    • compose/1/docker-compose.yml
    • compose/2/docker-compose.yml
  • Resultado:
  • los backups se generan
  • contienen datos validos
  • pueden restaurarse teoricamente sin tocar produccion

Fase 6 - RTO y RPO con evidencia real

  • La masa total dedicada a restaurar es pequena, menor a 2.5 MB sin compresion pesada adicional.
  • La simulacion genero y extrajo los tres backups en la misma sesion sin errores de integridad.
  • RTO certificado:
  • mismo VPS, contenedores o datos restaurados: 30-45 minutos
  • VPS nuevo desde cero: 90-180 minutos
  • RPO certificado:
  • 0 para la copia obtenida en la simulacion puntual
  • recurrente esperado: 24 horas por backup diario

Fase 7 - Implementacion recurrente validada 2026-05-31

  • SAFE POINT local inicial de esta implementacion:
  • git status -sb -> ## main...origin/main
  • git rev-parse HEAD -> 32ad551e89714e6a6d16bd99d4a2df7e74f6d878
  • VPS validado:
  • hostname -> srv977009
  • docker ps -> OpenClaw healthy, NPM up, Portainer up
  • Corrida manual validada:
  • /root/openclaw-backups/daily/20260531-014038
  • Checksums reales de la corrida final:
  • openclaw-stack.tgz 9169e9361aad7ef09e98ab08346d296d3c5ee00da43d47b63c7bbb996986cb00
  • npm-stack.tgz 753dad1908e26870aa8e935429df03318f05b7a93ab3050748758c7520788246
  • portainer-volume.tgz ee35d0930b602c5f82ce6b24cb6dc6ec19033cab90f5ffb310deb5745af0f7ab
  • Manifest y log:
  • manifest.txt presente
  • SHA256SUMS presente
  • log presente en /root/openclaw-backups/logs/openclaw-backup-20260531-014038.log
  • Semanal:
  • 2026-week22 creado sin duplicar al repetir la corrida del mismo domingo
  • Copia externa validada:
  • C:\APV\backups\openclaw\daily\20260531-014038
  • log local: C:\APV\backups\openclaw\logs\pull-openclaw-backups-20260531-014048.log

Fase 8 - Certificacion final

  • Certificacion final: VERDE

Base de la decision

  • Hay evidencia real de inventario, backup y restore de staging.
  • La auth OpenAI quedo localizada y no depende del directorio vacio auth-profile-secrets.
  • NPM y OpenClaw ya no dependen solo de snapshots implícitos.
  • El restore paso de teorico a demostrable en entorno controlado.

Riesgos encontrados

  • El snapshot del proveedor no fue revalidado en panel en esta sesion.
  • portainer.db se respalda como binario propio y no como SQLite logico.
  • El RPO futuro depende de que cron siga habilitado y de revisar periodicamente los logs de ejecucion.
  • La copia externa sigue siendo manual hasta aprobar una automatizacion controlada en Windows.
  • Los backups contienen secretos operativos; deben quedar fuera de Git y del workspace.

Checklist de cierre

  1. SAFE POINT inicial: SI
  2. Inventario completo: SI
  3. Evidencia backups: SI
  4. Evidencia persistencia auth: SI
  5. Riesgos encontrados: SI
  6. Archivos modificados:
  7. docs/BACKUP-RESTORE-STRATEGY.md
  8. docs/DISASTER-RECOVERY-RUNBOOK.md
  9. docs/PROJECT-STATE.md
  10. docs/ROADMAP.md
  11. scripts/README.md
  12. scripts/dr/README.md
  13. scripts/dr/Invoke-DrBackupRestoreEvidence.ps1
  14. Commit SHA base: 6445ca4e989d3ac287ce658ec4badf96ac006476
  15. git status final: validar al cierre local
  16. Certificacion final: VERDE
  17. Proximo paso unico recomendado: automatizar la descarga externa con Task Scheduler solo despues de validar espacio, politicas de retencion local y resguardo del equipo