Disaster Recovery — CreaRack Pro
Fecha: 07-04-2026 · Actualizado: 02-07-2026 (auditoría s185 — lista de secrets sincronizada con compose.prod.yml)
Objetivo: Restaurar CreaRack Pro desde cero en un servidor nuevo
Tiempo estimado: 45-60 minutos (con backups disponibles)
Audiencia: Edu, Dani
Requisitos previos
| Recurso | Dónde encontrarlo |
|---|---|
| Backup PostgreSQL (.sql.gz) | Hetzner Object Storage: crearack-backups-lock/postgres/ (desde el 24-09-2026; depósito con bloqueo de borrado de 30 días. El antiguo crearack-backups se vacía hacia el 24-10-2026) |
| Código fuente | GitHub: CreaRackSL/CreaRack-Pro |
| Variables de entorno (12 secrets) | Panel Dokploy → Compose → Environment |
| Certificados SSL | Auto-generados por Let’s Encrypt (no hay que restaurar) |
| Media files (stencils, signage) | Docker volume app_media (654 MB) — sin backup offsite actualmente |
| DNS | Cloudflare → apuntar A record a la nueva IP |
Secrets necesarios (guardar en lugar seguro)
Fuente de verdad: las variables declaradas en
compose.prod.yml(servicioweb/worker). Si esta tabla y el compose divergen, manda el compose.
| Variable | Descripción |
|---|---|
DJANGO_SECRET_KEY | Clave criptográfica Django |
POSTGRES_PASSWORD | Password PostgreSQL |
REDIS_PASSWORD | Password Valkey |
CREDENTIAL_ENCRYPTION_KEY | Cifrado at-rest de credenciales de dispositivos (¡distinta a propósito en STAGE vs PROD!) |
GEMINI_API_KEY | API key Google AI Studio (Gemma — Regla 8) |
ANTHROPIC_API_KEY | API key Anthropic (fallback del router IA; puede estar vacía) |
RESEND_API_KEY | API key Resend (email) |
GITHUB_TOKEN | Token GitHub (deploys) |
WORKSPACE_API_KEY | Integración con el workspace |
WORKSPACE_MCP_TOKEN | Token MCP del workspace |
CF_ACCESS_CLIENT_SECRET | Service token CF Access |
INTERNAL_TOOLS_TOKEN | Auth de herramientas internas |
— eliminada (proveedor retirado, key revocada el 16-05-2026; Regla 8 = solo Gemma vía Google AI Studio).DEEPSEEK_API_KEY
IMPORTANTE: Estos secrets solo están en el panel Dokploy. Si pierdes el servidor sin haberlos respaldado, necesitarás regenerar todos.
Paso 1 — Servidor nuevo Hetzner (10 min)
- Hetzner Cloud Console → Create Server
- Configuración:
- OS: Ubuntu 24.04 LTS
- Tipo: CCX (dedicated vCPU) — mínimo 4 vCPU / 16 GB RAM
- Datacenter: eu-central (Falkenstein o Nuremberg)
- SSH Key: añadir tu clave pública Ed25519
- Firewall: aplicar reglas existentes (22, 80, 443)
- Backups: activar desde el inicio
- Anotar la IP pública del nuevo servidor
O restaurar desde snapshot
Si tienes un snapshot reciente de Hetzner:
- Hetzner Cloud Console → Snapshots → seleccionar el más reciente
- Create Server from Snapshot
- Verificar que todo arranca:
docker ps,curl localhost:8000/health - Actualizar DNS en Cloudflare
- FIN — no necesitas el resto de pasos
Paso 2 — Setup base del servidor (10 min)
# Conectar al nuevo servidor
ssh root@<NUEVA_IP>
# Actualizar sistema
apt update && apt upgrade -y
# Instalar dependencias
apt install -y fail2ban netfilter-persistent iptables-persistent rclone
# Configurar SSH (si no viene del snapshot)
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
# Crear usuario con acceso SSH
# (o verificar que tu clave pública está en /root/.ssh/authorized_keys si usas root)
Paso 3 — Docker + Dokploy (10 min)
# Instalar Docker
curl -fsSL https://get.docker.com | sh
# Verificar
docker --version
docker compose version
# Instalar Dokploy (esto inicializa Docker Swarm automáticamente)
curl -sSL https://dokploy.com/install.sh | sh
# Verificar Dokploy
docker service ls
# Debe mostrar: dokploy, dokploy-postgres, dokploy-redis
Configurar Dokploy
- Abrir
http://<NUEVA_IP>:3000en el navegador - Crear cuenta admin
- Projects → Create → tipo Compose
- Conectar con GitHub repo
CreaRackSL/CreaRack-Pro - Compose file:
compose.prod.yml - Environment: añadir las 12 variables secretas + las públicas:
# Públicas
DJANGO_SETTINGS_MODULE=config.settings.production
DJANGO_ALLOWED_HOSTS=crearack.com,www.crearack.com,localhost,<NUEVA_IP>
CSRF_TRUSTED_ORIGINS=https://crearack.com,https://www.crearack.com
POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_DB=crearack_pro
POSTGRES_USER=crearack_user
VICTORIAMETRICS_URL=http://victoriametrics:8428
MIB_CACHE_DIR=/app/mib_cache
# Secrets (reemplazar con valores reales — lista completa en la tabla de arriba)
DJANGO_SECRET_KEY=<valor>
POSTGRES_PASSWORD=<valor>
REDIS_PASSWORD=<valor>
CREDENTIAL_ENCRYPTION_KEY=<valor>
GEMINI_API_KEY=<valor>
ANTHROPIC_API_KEY=<valor>
RESEND_API_KEY=<valor>
GITHUB_TOKEN=<valor>
WORKSPACE_API_KEY=<valor>
WORKSPACE_MCP_TOKEN=<valor>
CF_ACCESS_CLIENT_SECRET=<valor>
INTERNAL_TOOLS_TOKEN=<valor>
- Deploy — esperar a que todos los contenedores arranquen
Paso 4 — Restaurar base de datos (5 min)
# Descargar último backup del Object Storage
mkdir -p /opt/backups/postgres
rclone copy hetzner:crearack-backups-lock/postgres/ /opt/backups/postgres/ --include "*$(date +%Y-%m-%d)*"
# Si no hay backup de hoy, listar disponibles:
rclone ls hetzner:crearack-backups-lock/postgres/
# Si alguien "borró" copias, siguen como versiones ocultas durante 30 días (bloqueo)
# y 7 más tras marcarse como borradas: listarlas y recuperarlas con la herramienta de Amazon
# /opt/backups/s3api.sh s3api list-object-versions --bucket crearack-backups-lock --prefix postgres/
# /opt/backups/s3api.sh s3api get-object --bucket crearack-backups-lock --key <clave> --version-id <id> <fichero>
# (en un servidor nuevo, s3api.sh y la config de rclone hay que recrearlos: ver server-management §Object Storage)
# Descomprimir
LATEST=$(ls -t /opt/backups/postgres/*.sql.gz | head -1)
gunzip -k ${LATEST}
SQL_FILE="${LATEST%.gz}"
# Restaurar en PostgreSQL
# Primero, borrar la BD creada por el deploy y recrearla limpia
docker exec crearack-pro-zcmvsl-db-1 psql -U crearack_user -d postgres -c "DROP DATABASE IF EXISTS crearack_pro;"
docker exec crearack-pro-zcmvsl-db-1 psql -U crearack_user -d postgres -c "CREATE DATABASE crearack_pro OWNER crearack_user;"
# Restaurar dump
cat ${SQL_FILE} | docker exec -i crearack-pro-zcmvsl-db-1 psql -U crearack_user crearack_pro
# Verificar
docker exec crearack-pro-zcmvsl-db-1 psql -U crearack_user crearack_pro -c "SELECT count(*) FROM core_organization;"
# Aplicar migraciones pendientes (si las hay)
docker exec crearack-pro-zcmvsl-web-1 python manage.py migrate --noinput
# Reiniciar web para limpiar caches
docker restart crearack-pro-zcmvsl-web-1
Recuperación granular con WAL/PITR
Si el pg_dump es demasiado antiguo y se necesita recuperación más precisa, usar Point-in-Time Recovery con los archivos WAL:
# Los base backups físicos están en Object Storage bajo el prefijo basebackup/
# (corregido el 24-09-2026: la guía decía base_backups/, prefijo que nunca existió)
rclone ls hetzner:crearack-backups-lock/basebackup/
# Los archivos WAL archivados están bajo el prefijo wal/ (antes la guía decía wal_archives/)
rclone ls hetzner:crearack-backups-lock/wal/
# Proceso PITR:
# 1. Descargar el base backup más reciente anterior al punto de recuperación
# 2. Restaurar en el directorio de datos de PostgreSQL
# 3. Crear recovery.conf (o postgresql.conf en PG12+) con restore_command y recovery_target_time
# 4. Iniciar PostgreSQL — aplicará los WAL automáticamente hasta el punto especificado
Los WAL se sincronizan cada 15 minutos al Object Storage (
wal_sync.sh). La pérdida máxima de datos con PITR es ~15 minutos. Con pg_dump es hasta 24 horas (cron nocturno). Procedimiento completo: [[crearack-tech—guides—database-admin-guide]] (la antiguaDocumentation/guides/DATABASE_ADMIN_GUIDE.mddel repo fue archivada en abril 2026).
Configurar rclone (para futuros backups)
mkdir -p /root/.config/rclone
cat > /root/.config/rclone/rclone.conf << 'EOF'
[hetzner]
type = s3
provider = Other
access_key_id = <TU_ACCESS_KEY>
secret_access_key = <TU_SECRET_KEY>
endpoint = nbg1.your-objectstorage.com
region = nbg1
acl = private
EOF
Paso 5 — Firewall (2 min)
# Crear script de restauración
cat > /root/restore-firewall.sh << 'SCRIPT'
#!/bin/bash
set -e
for i in $(seq 1 30); do
if iptables -L DOCKER-USER -n &>/dev/null; then break; fi
sleep 2
done
iptables -F DOCKER-USER
iptables -A DOCKER-USER -s 127.0.0.0/8 -p tcp --dport 8000 -j ACCEPT
iptables -A DOCKER-USER -s 172.16.0.0/12 -p tcp --dport 8000 -j ACCEPT
iptables -A DOCKER-USER -p tcp --dport 8000 -j DROP
iptables -A DOCKER-USER -s 93.176.0.0/16 -p tcp --dport 3000 -j ACCEPT
# GitHub webhook IPs para auto-deploy de Dokploy (puerto 3000)
iptables -I DOCKER-USER -s 192.30.252.0/22 -p tcp --dport 3000 -j ACCEPT
iptables -I DOCKER-USER -s 185.199.108.0/22 -p tcp --dport 3000 -j ACCEPT
iptables -I DOCKER-USER -s 140.82.112.0/20 -p tcp --dport 3000 -j ACCEPT
iptables -I DOCKER-USER -s 143.55.64.0/20 -p tcp --dport 3000 -j ACCEPT
iptables -A DOCKER-USER -p tcp --dport 3000 -j DROP
iptables -A DOCKER-USER -j RETURN
echo "[$(date)] Firewall rules restored"
SCRIPT
chmod +x /root/restore-firewall.sh
# Crear systemd service
cat > /etc/systemd/system/restore-firewall.service << 'UNIT'
[Unit]
Description=Restore CreaRack iptables DOCKER-USER rules
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/root/restore-firewall.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload
systemctl enable restore-firewall.service
/root/restore-firewall.sh
Paso 6 — Backup cron (2 min)
# Crear script de backup
mkdir -p /opt/backups/postgres
cat > /opt/backups/pg_backup.sh << 'SCRIPT'
#!/bin/bash
BACKUP_DIR=/opt/backups/postgres
CONTAINER=crearack-pro-zcmvsl-db-1
DATE=$(date +%Y-%m-%d_%H%M)
BACKUP_FILE=${BACKUP_DIR}/crearack_pro_${DATE}.sql.gz
BUCKET=hetzner:crearack-backups/postgres/
docker exec ${CONTAINER} pg_dump -U crearack_user crearack_pro | gzip > ${BACKUP_FILE}
if [ $? -ne 0 ] || [ ! -s "${BACKUP_FILE}" ]; then
echo "[$(date)] BACKUP FAILED"
exit 1
fi
echo "[$(date)] Local backup: ${BACKUP_FILE} ($(du -h ${BACKUP_FILE} | cut -f1))"
rclone copy ${BACKUP_FILE} ${BUCKET} --quiet
if [ $? -eq 0 ]; then
echo "[$(date)] Offsite sync OK"
else
echo "[$(date)] OFFSITE SYNC FAILED"
fi
find ${BACKUP_DIR} -name '*.sql.gz' -mtime +14 -delete
rclone delete ${BUCKET} --min-age 30d --quiet 2>/dev/null
echo "[$(date)] Cleanup done (local 14d, remote 30d)"
SCRIPT
chmod +x /opt/backups/pg_backup.sh
# Programar cron
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/backups/pg_backup.sh >> /opt/backups/pg_backup.log 2>&1") | crontab -
# Verificar
crontab -l
Paso 7 — DNS (5 min)
- Cloudflare Dashboard → DNS →
crearack.com - Editar registro A → nueva IP del servidor
- Verificar:
dig crearack.com→ debe mostrar la nueva IP - Esperar propagación DNS (TTL, normalmente 5-30 min con Cloudflare)
Paso 8 — Verificación final
# 1. Contenedores corriendo
docker ps --format 'table {{.Names}}\t{{.Status}}'
# 2. Health check
curl -s https://crearack.com/health
# Esperado: {"status": "ok", ...}
# 3. SSL válido
curl -sI https://crearack.com | head -5
# Esperado: HTTP/2 200, sin errores SSL
# 4. Admin accesible
curl -s -o /dev/null -w "%{http_code}" https://crearack.com/admin/
# Esperado: 200 o 302 (redirect a login)
# 5. API docs
curl -s -o /dev/null -w "%{http_code}" https://crearack.com/api/docs
# Esperado: 200
# 6. Firewall verificado
iptables -L DOCKER-USER -n -v
# 7. UptimeRobot
# Verificar que el monitor vuelve a verde
Checklist resumen
- Servidor Hetzner creado (o restaurado desde snapshot)
- Ubuntu actualizado, fail2ban instalado
- Docker + Dokploy instalados
- Repo GitHub conectado, compose.prod.yml seleccionado
- Variables de entorno configuradas (12 secrets + públicas)
- Deploy ejecutado, contenedores arrancados
- Base de datos restaurada desde backup offsite
- rclone configurado para futuros backups
- Firewall iptables + systemd service
- Cron de backup diario
- DNS actualizado en Cloudflare
- SSL funcionando (auto Let’s Encrypt)
- Health check OK
- UptimeRobot verificado
Datos de referencia rápida
| Dato | Valor actual |
|---|---|
| IP servidor | 116.203.31.166 |
| OS | Ubuntu 24.04.4 LTS |
| Docker | 29.2.1 |
| Dokploy | v0.28.8 |
| Traefik | v3.6.7 |
| PostgreSQL | 18-alpine |
| DB size | ~20 MB |
| Media size | ~654 MB |
| Backup offsite | hetzner:crearack-backups/postgres/ (nbg1) |
| Backup local | /opt/backups/postgres/ (14 días) |
| Backup remoto | 30 días retención |
| Contenedores | 10 (6 app + 4 Dokploy) |
| Volúmenes | 8 persistentes |
Qué NO está cubierto por este procedimiento
| Dato | Situación | Mitigación futura |
|---|---|---|
| Media files (stencils, signage uploads) | Solo en Docker volume local — no hay backup offsite | Añadir rclone sync de /app/media |
| VictoriaMetrics (métricas 180 días) | Solo en Docker volume local | Repoblable desde dispositivos, baja prioridad |
| Dokploy config (projects, env vars) | En la BD interna de Dokploy | Exportar secrets a archivo cifrado |
| Valkey data | AOF en Docker volume | Cache reconstruible, no crítico |
Recuperación de Staging
El servidor de staging (178.104.131.173, CX23) sigue el mismo procedimiento con estas diferencias:
| Parámetro | Producción | Staging |
|---|---|---|
| Tipo servidor Hetzner | CCX (4 vCPU, 16 GB) | CX23 (1 vCPU, 4 GB) |
SECURE_COOKIES | true | false (HTTP sin SSL) |
| DNS | crearack.com | IP directa o subdominio staging |
| WAL archiving | Sí | No |
| Backups offsite | Sí | No |
El staging no tiene pg_dump ni WAL configurados. La BD se restaura manualmente desde un backup de producción si es necesario.
Generado por: Claude (Anthropic) + Edu Fecha: 07-04-2026
Véase también
- [[crearack-tech—admin—backup-restore]] — backup y restore
- [[crearack-tech—guides—database-admin-guide]] — administración de la BD
- [[crearack-tech—admin—hetzner-ssh-setup]] — acceso SSH a Hetzner
- [[crearack-tech—guides—production-deployment]] — deploy en producción Hetzner
- [[crearack-tech—guides—deploy-checklist]] — checklist de deploy Golden Path
- [[workspace—guias—disaster-recovery-workspace]] — DR del workspace
- [[crearack-tech—reports—infrastructure-robustness-audit-04-04-2026]] — auditoría de robustez infra
Referenciado desde
- Auditoría de Robustez Infraestructural — CreaRack Pro SaaS
- Backup & Restore - CreaRack Pro
- Deploy Checklist — Golden Path
- Disaster Recovery — CreaRackSL Workspace
- Guía de Administración de Base de Datos — CreaRack Pro
- Guía de Producción — CreaRack Pro en Hetzner
- Hetzner STAGE (178.104.131.173) — inventario y plan de réplica
- Manual de Seguridad y Backups — Esferic Labs / CreaRack (fuente única)
- Proxmox VE 9.1 sobre Hetzner EPYC 7502P — Setup y Operación
- Server Management — Hetzner + Ubuntu
- Valkey Persistence Patterns - CreaRack Pro