Cómo copiar archivos entre VPS con SCP y Rsync — guía práctica
Aprende a copiar archivos entre VPS, desde la máquina local o entre servidores remotos usando SCP y Rsync con ejemplos prácticos y flags útiles.
Transferir archivos entre servidores vía terminal es una de las operaciones más comunes en el día a día de quien administra un VPS. Ya sea para subir código a producción, mover backups entre regiones o migrar datos entre máquinas, SCP y Rsync son las herramientas estándar — ambas corren sobre SSH y no exigen instalación de un daemon adicional en la mayoría de los casos.
La elección entre las dos raramente es “cuál es mejor” y más frecuentemente “cuál encaja en el escenario”. SCP brilla en transferencias puntuales simples, generalmente un archivo o directorio pequeño copiado una vez. Rsync brilla en cualquier cosa recurrente, en volúmenes grandes o donde la red puede fallar y necesitas reanudar.
Esta guía muestra los comandos exactos para tres escenarios: local → VPS, VPS → local y VPS → VPS. Tiempo estimado de lectura y ejecución de los ejemplos: 15-20 minutos.
Requisitos previos
Necesitas acceso SSH funcional a ambas máquinas involucradas. Si aún no configuraste claves SSH, recomiendo hacerlo antes — copiar archivos escribiendo contraseña en cada conexión se vuelve inviable rápido. Los ejemplos asumen Linux o macOS en el cliente; en Windows, usa WSL2 o PowerShell con OpenSSH habilitado.
Datos técnicos típicos para completar en los comandos:
root o tu usuario sudo 22 (por defecto) IP o hostname del VPS Confirma el acceso básico antes de intentar transferir:
ssh [email protected]
Si el login funciona sin solicitar contraseña (o pide solo la passphrase de la clave), estás listo.
Copiando con SCP — sintaxis básica
SCP sigue el patrón scp [opciones] origen destino. Origen o destino
pueden ser locales (ruta normal) o remotos (usuario@host:ruta).
Copia un archivo local al VPS:
scp ./backup.tar.gz [email protected]:/var/backups/El ./backup.tar.gz es el archivo local. El destino remoto es el
directorio /var/backups/ en el VPS. La barra final en el destino es
importante — sin ella, el archivo sería renombrado a backups.
Copia un directorio entero recursivamente:
scp -r ./mi-proyecto [email protected]:/var/www/La flag -r activa el modo recursivo. Sin ella, SCP rechaza
directorios. El directorio mi-proyecto será creado dentro de
/var/www/ en el destino.
Descarga un archivo del VPS a la máquina local:
scp [email protected]:/var/log/nginx/access.log ./La dirección se define por el orden de los argumentos. El ./ indica
el directorio actual en el cliente.
Copia directamente entre dos VPS usando la flag -3:
scp -3 [email protected]:/data/db.sql [email protected]:/tmp/Sin -3, SCP intenta establecer SSH entre los dos VPS, lo que exige
que tengan claves registradas una en la otra. Con -3, los datos
pasan por tu cliente local actuando como enrutador — más lento, pero
funciona sin configuración adicional.
Flags SCP útiles en el día a día
-P 2222— especifica puerto SSH (P mayúscula en SCP, diferente del-pminúscula de SSH)-p(minúscula) — preserva timestamps y modos del archivo original-q— modo silencioso, suprime barra de progreso (útil en scripts)-l 5000— limita ancho de banda en kbit/s, evita saturar el enlace del VPS-i ~/.ssh/clave_especifica— usa una clave SSH específica en lugar de la predeterminada
A partir de OpenSSH 9.0, el protocolo SCP usa SFTP por debajo por cuestiones de seguridad. Los comandos siguen funcionando idénticamente, pero si ves mensajes sobre “protocolo legado”, sabe que no es un error — es informativo. Para nuevas integraciones, considera SFTP o Rsync.
Copiando con Rsync — eficiencia en volumen
Rsync usa un algoritmo de diff que compara origen y destino bloque a bloque. En una sincronización repetida, transfiere solo lo que cambió — ganancia enorme en directorios grandes.
Sincroniza un directorio local al VPS:
rsync -avz ./sitio/ [email protected]:/var/www/sitio/Las flags significan:
-a(archive): preserva permisos, propietarios, timestamps, enlaces simbólicos, recursivo-v(verbose): muestra archivos siendo transferidos-z(compress): comprime datos en tránsito, reduce ancho de banda en ~30-60% para archivos de texto
Atención a la barra final en el origen: ./sitio/ copia el
contenido del directorio. Sin la barra (./sitio), copiaría el
directorio sitio dentro del destino, creando /var/www/sitio/sitio/.
Agrega barra de progreso y reanudación automática:
rsync -avzP ./backup.tar.gz [email protected]:/backups/La flag -P es atajo para --partial --progress. Muestra velocidad,
ETA y mantiene archivos parciales en caso de interrupción — basta
ejecutar el mismo comando nuevamente para reanudar.
Excluye directorios innecesarios:
rsync -avzP \
--exclude='node_modules' \
--exclude='.git' \
--exclude='*.log' \
./proyecto/ [email protected]:/var/www/proyecto/Cada --exclude acepta patrones glob. También puedes usar
--exclude-from=archivo.txt para cargar una lista de una sola vez.
Sincroniza entre dos VPS ejecutando el comando dentro de uno de ellos:
ssh [email protected] \
"rsync -avzP /data/ [email protected]:/data/"Aquí Rsync corre dentro del vps1, evitando el cuello de botella de pasar por tu cliente. Exige que vps1 tenga clave SSH registrada en vps2.
Agrega --dry-run (o -n) para simular la operación sin transferir
nada. Combina bien con -v para ver exactamente lo que sería copiado y
eliminado. Esencial antes de usar --delete, que borra en el destino
archivos que no existen en el origen.
Flags Rsync que ahorran tiempo
| Flag | Qué hace |
|---|---|
--delete | Elimina en el destino archivos que desaparecieron del origen — sincronización real |
--bwlimit=5000 | Limita ancho de banda en KB/s |
--checksum | Compara vía checksum (más lento, más seguro que timestamp) |
-e "ssh -p 2222" | SSH en puerto no estándar |
--numeric-ids | Preserva uid/gid numéricamente, útil en backups |
--append-verify | Reanuda archivo parcial validando checksum de los bloques ya enviados |
Verificación después de la transferencia
Confirmar que los archivos llegaron íntegros es parte del proceso. Compara conteo y checksum.
Cuenta archivos en origen y destino:
# Local
find ./proyecto -type f | wc -l
# Remoto
ssh [email protected] "find /var/www/proyecto -type f | wc -l"Los números deben coincidir exactamente, descontando exclusiones aplicadas.
Compara checksum de archivo crítico:
# Local
sha256sum backup.tar.gz
# Remoto
ssh [email protected] "sha256sum /backups/backup.tar.gz"Hashes idénticos confirman integridad bit a bit.
Resolución de problemas
Permission denied (publickey)
Tu clave SSH no está siendo aceptada. Verifica si la clave pública está
en ~/.ssh/authorized_keys en el servidor y si los permisos son
correctos (700 en el directorio .ssh, 600 en el archivo). Prueba
con ssh -v usuario@host para ver el handshake completo e identificar
qué clave fue ofrecida.
No space left on device
Destino sin espacio. Verifica con df -h en el servidor y libera antes
de intentar nuevamente. Rsync con --partial mantiene el archivo
parcial, así que reanudar funciona después de que liberes espacio.
Connection timed out durante transferencia larga
La conexión SSH expiró. Agrega ServerAliveInterval 60 en tu
~/.ssh/config o usa rsync -e "ssh -o ServerAliveInterval=60" para
enviar keepalives. En transferencias de horas, esto evita que NAT
intermedio derribe la sesión.
Próximos pasos
Con SCP y Rsync dominados, cubres el 90% de las transferencias del día a día. Para ir más allá:
- Configura claves SSH con passphrase + agente SSH para productividad
- Automatiza backups con Rsync vía cron, escribiendo en
/etc/cron.d/ - Explora
rsnapshotpara backups incrementales con hardlinks - Considera SSHFS para montar directorios remotos como filesystem local
- Para transferencias entre regiones geográficas distantes, evalúa
herramientas como
bbcpombufferque paralelizan streams
Si estás colocando esto en producción, un VPS Hostini ya viene con SSH endurecido por defecto y enlace de red dimensionado para sostener transferencias continuas sin throttle — útil tanto para deploy como para backups recurrentes.
Preguntas frecuentes
¿Cuál es la diferencia práctica entre SCP y Rsync?
SCP copia todo de una sola vez sin comparar el destino — simple, pero reenvía el archivo entero si lo ejecutas de nuevo. Rsync compara origen y destino bloque a bloque, transfiere solo el diff y admite reanudación. Para archivos pequeños y únicos, SCP es más rápido de escribir. Para directorios grandes o sincronización recurrente, Rsync gana siempre.
¿Puedo copiar archivos de un VPS directamente a otro sin pasar por mi computadora?
Sí. Tanto SCP como Rsync aceptan origen y destino remotos en la misma línea, ej: `scp user1@vps1:/path/file user2@vps2:/path/`. El cliente local actúa como intermediario de control, pero los datos pueden viajar directamente si usas `-3` en SCP o ejecutas el comando dentro de uno de los VPS vía SSH.
¿Cómo reanudar una transferencia Rsync interrumpida?
Usa las flags `--partial --append-verify`. El `--partial` mantiene el archivo parcial en el destino, y el `--append-verify` reanuda desde donde se detuvo validando el checksum de los bloques ya enviados. Combinado con `-P` (que es `--partial --progress`), tienes reanudación y barra de progreso.
¿Es seguro copiar con la flag --exclude para ignorar carpetas grandes?
Sí, y es recomendado. Siempre excluye `node_modules`, `vendor`, `.git`, `*.log` y cachés que pueden ser reconstruidos en el destino. Ejemplo: `rsync -avz --exclude='node_modules' --exclude='.git' src/ dest/`. Reduce drásticamente el volumen transferido sin perder integridad del proyecto.
¿Por qué mi transferencia SCP está extremadamente lenta?
SCP usa cifrado AES-128-CTR por defecto, que es seguro pero costoso en CPU. En VPS con enlace rápido y CPU limitada, el cuello de botella se convierte en el cifrado. Prueba `scp -c [email protected]` o cambia a Rsync sobre SSH, que tiene compresión (`-z`) y un protocolo más eficiente con múltiples archivos.
¿Cómo copiar archivos preservando permisos y propietarios?
En SCP, usa la flag `-p` para preservar timestamps y modos. En Rsync, usa `-a` (modo archivo), que ya incluye preservación de permisos, propietarios, grupos, timestamps y enlaces simbólicos. Para preservar uid/gid numéricamente en lugar de mapear por nombre, agrega `--numeric-ids` en Rsync.