
🌐 También en: English · Deutsch · Français
(Este artículo es la continuación lógica del script de copia de seguridad descrito aquí: Nextcloud Backup Like a Pro – Automated with Bash. Ambos artículos van de la mano y completan el flujo de trabajo de migración y recuperación ante desastres.)
Tras varios años con una fiel instancia de Nextcloud –con un sinfín de archivos de usuarios, calendarios, contactos y carpetas compartidas de lo más pintorescas–, tocaba renovarse. El servidor antiguo empezaba a notar el paso del tiempo, y ya había una máquina nueva y reluciente aprovisionada con Ansible para empezar de cero.
En lugar de pelearme con exportaciones manuales, interfaces web poco fiables o plugins de copia de seguridad en el navegador, opté por un script de Bash ligero y contundente que se encargara de toda la migración. Con él pude trasladar todo el stack de Nextcloud (archivos del núcleo, datos de usuarios y base de datos) al nuevo servidor, de forma reproducible y con un tiempo de inactividad mínimo.
🧠 Qué hace este script
- Detiene los servicios de forma ordenada en el servidor de destino para evitar bloqueos de archivos o conflictos.
- Sincroniza los archivos de la aplicación Nextcloud (excluyendo el directorio
data/). - Transfiere los datos de usuarios por separado a su nueva ruta de destino.
- Restaura la base de datos a partir de un volcado local usando
scpymysql. - Corrige propietarios y permisos para que el servidor web pueda acceder.
- Reinicia PHP y los servicios web cuando todo está en su sitio.
- Confirma que ha terminado con un mensaje de estado final.
📁 Notas sobre la estructura de directorios
Como parte de la migración, también trasladamos el directorio data/ a una ubicación propia fuera de la raíz web de Apache. Es un enfoque más limpio y seguro que guardar los datos de usuarios dentro del directorio principal de instalación de Nextcloud (que era lo que ocurría antes).
El script tiene en cuenta este cambio: transfiere la carpeta data/ por separado y la coloca en su nueva ubicación externa en el servidor de destino.
⚙️ El script de migración
#!/bin/bash
# === CONFIGURATION ===
REMOTE_USER="root"
REMOTE_HOST="your.remote.ip"
REMOTE_SSH_PORT=22
SSH_KEY="$HOME/.ssh/id_rsa"
BACKUP_DIR="/data/backup/nextcloud/instance-a"
REMOTE_NEXTCLOUD_DIR="/var/www/html/nextcloud"
REMOTE_DATA_DIR="/data"
DB_NAME="your.db.name"
DB_USER="your.user"
DB_PASS="********" # 🔐 Password removed for security
WWW_USER="www-data"
SSH_CMD="ssh -i $SSH_KEY -p $REMOTE_SSH_PORT -o LogLevel=ERROR $REMOTE_USER@$REMOTE_HOST"
echo "🛑 [1/7] Stopping remote web and PHP services ..."
$SSH_CMD "systemctl stop apache2 2>/dev/null || systemctl stop httpd 2>/dev/null"
$SSH_CMD "systemctl stop php8.2-fpm 2>/dev/null || true"
echo "📤 [2/7] Transferring Nextcloud files (excluding data/) to remote server ..."
rsync -a --delete --exclude "data/" \
-e "ssh -i $SSH_KEY -p $REMOTE_SSH_PORT -o LogLevel=ERROR" \
"$BACKUP_DIR/nextcloud/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_NEXTCLOUD_DIR/"
echo "📤 [3/7] Transferring user data (nextcloud/data/) to remote /data ..."
rsync -a --delete \
-e "ssh -i $SSH_KEY -p $REMOTE_SSH_PORT -o LogLevel=ERROR" \
"$BACKUP_DIR/nextcloud/data/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DATA_DIR/"
echo "🛢️ [4/7] Transferring and restoring database dump ..."
scp -i "$SSH_KEY" -P $REMOTE_SSH_PORT "$BACKUP_DIR/db.sql" "$REMOTE_USER@$REMOTE_HOST:/tmp/db.sql"
$SSH_CMD "mysql -u '$DB_USER' -p'********' '$DB_NAME' < /tmp/db.sql && rm /tmp/db.sql" echo "🔒 [5/7] Setting remote file permissions ..." $SSH_CMD "chown -R '$WWW_USER:$WWW_USER' '$REMOTE_NEXTCLOUD_DIR'" $SSH_CMD "chown -R '$WWW_USER:$WWW_USER' '$REMOTE_DATA_DIR'" echo "🚀 [6/7] Starting remote services ..." $SSH_CMD "systemctl start php8.2-fpm 2>/dev/null || true"
$SSH_CMD "systemctl start apache2 2>/dev/null || systemctl start httpd 2>/dev/null"
echo "✅ [7/7] Remote restore complete. Please verify your Nextcloud instance at: https://$REMOTE_HOST"
🎉 Reflexiones finales
Migrar una instancia de Nextcloud en producción que lleva años funcionando –con datos reales y usuarios reales– puede imponer respeto. Pero con un enfoque estructurado y una buena automatización, no tiene por qué. Gracias a este script y a un entorno de destino limpio basado en Ansible, todo el proceso llevó menos de 30 minutos y no necesitó ningún retoque manual. ¡Fiesta nerd!
Si estás planeando tu propia migración de Nextcloud, sobre todo con grandes volúmenes de datos y cero margen para el error humano, prueba este enfoque y adáptalo a tu forma de montar la infraestructura.





