Sincronización de proyectos web con rsync
1. El caso real: desarrollo web desordenado pero productivo
Escenario típico:
- Sitio web en producción (HTML, PHP, JS, CSS)
- Repositorio local con Git
- Algunas ediciones rápidas directas en servidor
- Algunos archivos locales modificados
- Subida manual de archivos con gestor gráfico
- Miedo a borrar algo por error
Problema: Falta de sincronización eficiente y segura entre local y remoto.
2. rsync: la herramienta perfecta para sincronización
2.1 ¿Por qué rsync?
- Transferencia incremental → Solo envía archivos modificados
- Modo dry-run → Simula la operación antes de ejecutarla
- Preserva permisos y timestamps
- Detecta cambios automáticamente
- Exclusión de archivos no deseados
2.2 Sintaxis básica
rsync [opciones] origen destino
Opciones esenciales:
-a
→ Modo archivo (preserva permisos, timestamps, etc.)-v
→ Verbose (muestra qué archivos transfiere)-z
→ Comprime durante la transferencia--dry-run
→ Solo simula, no ejecuta--delete
→ Elimina archivos del destino que no existen en origen
3. Flujo de trabajo seguro
rsync
es demasiado meticuloso al comparar archivos. Si dos archivos "de contenido idéntico" tienen distinta fecha, o distinto propietario, o distintos permisos, se consideran distintos y rsync
los incluirá para actualizar, lo que no siempre o casi nunca es ideal, ya que por ejemplo el propietario del archivo (usuario) difícilmente tendrá el mismo nombre en local y remoto. rsync
ofrece muchas opciones para ajustar la comparación lo mas posible a tus deseos, por ejemplo ignorando en la comparación atributos como fechas o permisos, o comparando con checksum
Seguramente tendrás que afinar las opciones antes de lograr el resultado deseado: que no sincronice demasiado o demasiado poco. Por eso es esencial probar siempre primero con --dry-run
3.1 Siempre empezar con dry-run
# PASO 1: Ver qué va a pasar (SIEMPRE)
rsync -avz --dry-run /home/usuario/mi_web/ usuario@servidor.com:/var/www/html/
# PASO 2: Si te convence el resultado, ejecutar
rsync -avz /home/usuario/mi_web/ usuario@servidor.com:/var/www/html/
3.2 Interpretando la salida de dry-run
Ejemplo de salida típica:
$ rsync -avz --dry-run /home/usuario/mi_web/ usuario@servidor.com:/var/www/html/
sending incremental file list
./
index.php
css/
css/styles.css
js/script.js
admin/
admin/config.php
images/banner.jpg
sent 1,234 bytes received 156 bytes 277.78 bytes/sec
total size is 245,680 speedup is 176.79 (DRY RUN)
3.3 Salida detallada con itemize-changes
$ rsync -avzi --dry-run /home/usuario/mi_web/ usuario@servidor.com:/var/www/html/
.d..t...... ./
.f.st...... index.php
>f+++++++++ css/styles.css
.f..t...... js/script.js
*deleting old_banner.jpg
Interpretación de símbolos:
.
indica que no transfiere contenido, aunque puede modificar los atributos del archivof
od
indica que se trata de un archivo o directorio.f.st......
→ archivo modificado (size y time diferentes)>f+++++++++
→ archivo nuevo que se creará*deleting
→ archivo que se eliminará del destino.d..t......
→ directorio con timestamp diferente
Cada letra en las 9 posiciones siguientes indica qué cambió:
s
→ tamaño distintoc
→ checksum distinto (contenido distinto)t
→ marca de tiempo distintae
→ permisos distintoso
→ propietario distintog
→ grupo distintou
→ setuida
→ ACLx
→ atributo extendido
3.4 Modificadores
-avz # archivo --verbose --compress
--delete #elimina archivos en el directorio de destino si no existen en el directorio de origen
-r # recursivo
-c # checksum (ignora mtime/tamaño para decidir cambios; más lento pero exacto)
-n # --dry-run
-i itemize
--no-perms --no-owner --no-group # evita diferencias de p/o/g
--omit-dir-times # no compares tiempos de directorios
--exclude-from=.rsyncignore # tu ignore
4. Sincronización bidireccional
4.1 Descargar cambios del servidor (cuando editas en remoto)
# Ver qué cambios hay en el servidor
rsync -avz --dry-run usuario@servidor.com:/var/www/html/ /home/usuario/mi_web/
# Si todo OK, descargar
rsync -avz usuario@servidor.com:/var/www/html/ /home/usuario/mi_web/
4.2 Subir cambios locales
# Ver qué se va a subir
rsync -avz --dry-run /home/usuario/mi_web/ usuario@servidor.com:/var/www/html/
# Subir cambios
rsync -avz /home/usuario/mi_web/ usuario@servidor.com:/var/www/html/
5. Script de sincronización inteligente
5.1 Script básico para proyectos web
#!/bin/bash
# sync-web.sh
LOCAL="/home/tu_usuario/mi_proyecto/"
REMOTE="usuario@servidor.com:/var/www/html/"
echo "=== Sincronización de proyecto web ==="
echo "1) Bajar cambios del servidor"
echo "2) Subir cambios locales"
echo "3) Ver diferencias"
echo "4) Backup del servidor"
read -p "Opción (1/2/3/4): " opcion
case $opcion in
1)
echo "VISTA PREVIA - Descarga desde servidor:"
rsync -avz --dry-run $REMOTE $LOCAL
echo ""
read -p "¿Proceder con la descarga? (y/N): " confirm
[[ $confirm == "y" ]] && rsync -avz $REMOTE $LOCAL
;;
2)
echo "VISTA PREVIA - Subida al servidor:"
rsync -avz --dry-run --exclude-from=~/.rsync-exclude $LOCAL $REMOTE
echo ""
read -p "¿Proceder con la subida? (y/N): " confirm
[[ $confirm == "y" ]] && rsync -avz --exclude-from=~/.rsync-exclude $LOCAL $REMOTE
;;
3)
echo "=== Archivos diferentes entre local y servidor ==="
rsync -avz --dry-run --itemize-changes $LOCAL $REMOTE
;;
4)
echo "Creando backup del servidor..."
ssh usuario@servidor "tar -czf backup_$(date +%Y%m%d_%H%M).tar.gz -C /var/www html"
echo "Backup creado en el servidor"
;;
esac
5.2 Archivo de exclusiones ~/.rsync-exclude
# Archivos y carpetas a NO sincronizar
.git/
.gitignore
*.log
node_modules/
vendor/
.env
config_local.php
.htaccess.local
cache/
temp/
uploads/
*.tmp
.DS_Store
Thumbs.db
6. Protección anti-desastres
6.1 Backup automático antes de cambios importantes
#!/bin/bash
# deploy-safe.sh
SERVER="usuario@servidor.com"
REMOTE_PATH="/var/www/html"
LOCAL_PATH="/home/usuario/mi_web"
echo "Creando backup del servidor..."
ssh $SERVER "tar -czf ~/backup_$(date +%Y%m%d_%H%M%S).tar.gz -C /var/www html"
echo "Vista previa de cambios:"
rsync -avz --dry-run --delete $LOCAL_PATH/ $SERVER:$REMOTE_PATH/
read -p "¿Continuar con el deploy? (y/N): " confirm
if [[ $confirm == "y" ]]; then
rsync -avz --delete $LOCAL_PATH/ $SERVER:$REMOTE_PATH/
echo "Deploy completado"
else
echo "Deploy cancelado"
fi
6.2 Verificación post-sincronización
# Verificar que los archivos llegaron correctamente
rsync -avz --dry-run $LOCAL/ $REMOTE/
# Si no muestra archivos, significa que están sincronizados
7. Alternativas gráficas más amigables
7.1 Para quienes prefieren interfaces gráficas
Opciones recomendadas:
- Dolphin (KDE):
sftp://servidor.com
en barra de direcciones - VS Code con extensión "SFTP": edición y subida automática
- WinSCP: más intuitivo que FileZilla para sincronización, aunque solo para windows.
7.2 Integración con editores
// Configuración VS Code SFTP (.vscode/sftp.json)
{
"name": "Mi Servidor",
"host": "servidor.com",
"protocol": "sftp",
"port": 22,
"username": "usuario",
"remotePath": "/var/www/html",
"uploadOnSave": false,
"ignore": [".git", "node_modules", "*.log"]
}
8. Buenas prácticas para sincronización
- Siempre usar
--dry-run
antes del comando real - Crear backups antes de cambios importantes
- Usar archivos de exclusión para evitar transferir archivos innecesarios
- Verificar la conectividad antes de sincronizar
- Documentar qué archivos NO deben sincronizarse
- Probar en entorno de desarrollo antes de producción
Regla de oro: Si tienes dudas, haz dry-run. Si sigues con dudas, haz backup primero.
Tabla de referencia rápida de comandos
Comando | Descripción |
---|---|
ls |
Lista archivos en el servidor remoto |
cd carpeta |
Cambia directorio remoto |
lcd carpeta |
Cambia directorio local |
pwd |
Muestra directorio remoto actual |
lpwd |
Muestra directorio local actual |
get archivo |
Descarga archivo |
put archivo |
Sube archivo |
mget *.ext |
Descarga múltiples archivos |
mput *.ext |
Sube múltiples archivos |
binary |
Activa modo binario |
ascii |
Activa modo texto |
quote PASV |
Activa modo pasivo en FTP clásico |
mirror origen destino |
Descarga directorio completo (lftp) |
mirror -R origen destino |
Sube directorio completo (lftp) |
du -sh carpeta |
Muestra tamaño de archivos/carpetas |
rsync -avz --dry-run |
Simula sincronización con rsync |
bye |
Cierra conexión |