Rsync по SSH: синхронизация и резервное копирование файлов
Rsync копирует только изменения — не весь файл целиком, а только блоки которые отличаются от предыдущей версии. На практике это означает что первая синхронизация 10 ГБ занимает столько времени сколько нужно для передачи 10 ГБ, а следующая — секунды, если изменилось немного. При этом rsync работает поверх SSH без дополнительной настройки: если есть SSH-доступ к серверу, rsync уже готов к работе.
Базовый синтаксис
Скопировать файлы с локальной машины на удалённый сервер:
rsync -av /local/path/ user@server:/remote/path/
Скопировать с удалённого сервера на локальную машину:
rsync -av user@server:/remote/path/ /local/path/
Флаги -av используют почти всегда: -a сохраняет права доступа, временные метки, символические ссылки и рекурсивно обходит директории. -v показывает что именно копируется. Этот набор — разумный минимум для большинства задач.
Главная ловушка: слеш в конце пути
Наличие или отсутствие слеша в конце пути источника меняет поведение rsync кардинально. Это самая частая причина «неожиданного» результата.
Без слеша — rsync копирует саму директорию:
rsync -av /data/files /backup/
# Результат: /backup/files/
Со слешем — rsync копирует содержимое директории:
rsync -av /data/files/ /backup/
# Результат: /backup/файл1, /backup/файл2...
Простое правило: слеш в конце источника означает «возьми то, что внутри». Без слеша — «возьми саму папку». Путь назначения ведёт себя предсказуемо в обоих случаях — rsync создаёт его если нет.
Проверка перед запуском
Перед первым запуском с незнакомыми флагами — особенно с --delete — всегда делайте пробный запуск:
rsync -av --dry-run /data/ user@server:/backup/
Флаг --dry-run (или сокращённо -n) показывает что rsync сделал бы, не делая этого на самом деле. Вы увидите список файлов которые были бы скопированы или удалены. Убедились что всё верно — запускаете без --dry-run.
SSH ключи для автоматизации
Когда rsync запускается интерактивно, он запрашивает пароль через SSH — это нормально. Но если нужно запустить rsync через cron или в скрипте, пароль вводить некому.
Решение — SSH-ключ без парольной фразы специально для бэкапов:
ssh-keygen -t ed25519 -f ~/.ssh/backup_key -N ""
Флаг -N "" создаёт ключ без парольной фразы. Скопируйте публичную часть ключа на удалённый сервер:
ssh-copy-id -i ~/.ssh/backup_key user@remote-server
Теперь rsync подключается без пароля с явным указанием ключа:
rsync -av -e "ssh -i ~/.ssh/backup_key" /data/ user@server:/backup/
Этот вариант безопаснее чем хранить пароль в переменных окружения или конфиге — ключ без фразы используется только для одной цели и его можно отозвать в любой момент через ~/.ssh/authorized_keys на сервере.
Нестандартный SSH-порт
Если SSH на удалённом сервере работает не на стандартном 22 порту, укажите порт через флаг -e:
rsync -av -e "ssh -p 2222" /data/ user@server:/backup/
Частая ошибка: использовать флаг -p напрямую в rsync. Но -p в rsync означает совсем другое — preserve permissions (сохранять права доступа, часть флага -a). Для SSH-порта всегда используйте -e "ssh -p ПОРТ".
Синхронизация с удалением: флаг —delete
По умолчанию rsync только добавляет и обновляет файлы в назначении. Если файл удалили в источнике, в назначении он останется. Чтобы назначение было точным зеркалом источника, нужен флаг --delete:
rsync -av --delete /data/ user@server:/backup/
Будьте осторожны: --delete удаляет файлы в назначении которых нет в источнике. Без предварительного --dry-run это может привести к нежелательным потерям. Особенно аккуратно если в назначении хранятся данные из нескольких источников.
Исключение файлов и директорий
Чтобы не копировать временные файлы, кеш или логи:
rsync -av --exclude="*.log" --exclude="cache/" --exclude=".git" \
/var/www/ user@server:/backup/www/
Исключения применяются к путям относительно источника. Если нужно исключить много всего, удобнее вынести список в файл:
echo "*.log" >> ~/.rsync-exclude
echo "cache/" >> ~/.rsync-exclude
echo ".git" >> ~/.rsync-exclude
rsync -av --exclude-from="~/.rsync-exclude" /var/www/ user@server:/backup/www/
Ограничение скорости
Если нужно не перегружать канал при синхронизации больших объёмов:
rsync -av --bwlimit=5120 /data/ user@server:/backup/
Значение в КБ/с: 5120 = 5 МБ/с, 10240 = 10 МБ/с. Полезно при синхронизации в рабочие часы когда канал нужен для других задач.
Инкрементальные бэкапы с историей версий
Обычная синхронизация хранит только актуальную копию — если файл изменился или удалился, старая версия теряется. Флаг --link-dest решает это элегантно: создаёт жёсткие ссылки на неизменённые файлы вместо их копирования.
DATE=$(date +%Y-%m-%d)
DEST="/backup/snapshots"
LATEST="$DEST/latest"
rsync -av --link-dest="$LATEST" /var/www/ "$DEST/$DATE/"
ln -sfn "$DEST/$DATE" "$LATEST"
Каждый запуск создаёт директорию с датой которая выглядит как полная копия сайта, но на диске занимает только место изменившихся файлов — неизменённые файлы это просто ссылки на предыдущую версию. Откат к любому дню: просто зайти в нужную директорию.
Автоматизация через cron
Пример cron-задачи: синхронизация каждую ночь в 3:00 с логированием:
crontab -e
0 3 * * * rsync -av --delete -e "ssh -i /home/user/.ssh/backup_key" \
/var/www/ backup@backup-server:/backups/www/ \
>> /var/log/rsync-backup.log 2>&1
2>&1 перенаправляет и stdout и stderr в лог — если что-то пойдёт не так, ошибка будет в файле, а не потеряется.
Часто задаваемые вопросы
Нужно ли устанавливать rsync на обоих серверах?
Да, rsync должен быть установлен и на источнике и на назначении. Устанавливается одной командой: sudo apt install rsync на Ubuntu/Debian или sudo dnf install rsync на CentOS/AlmaLinux.
Почему rsync копирует файлы которые не изменились?
По умолчанию rsync сравнивает файлы по размеру и дате изменения. Если дата изменилась (например, после touch или копирования без сохранения атрибутов), rsync считает файл изменённым. Флаг --checksum заставляет rsync сравнивать по контрольной сумме — медленнее, но точнее.
Можно ли использовать rsync для бэкапа базы данных?
Rsync копирует файлы, и файлы базы данных во время работы СУБД могут быть в несогласованном состоянии. Для MySQL и PostgreSQL правильнее делать дамп (mysqldump, pg_dump) а потом rsync’ить файл дампа. Либо использовать снапшот файловой системы перед rsync.
Как проверить что синхронизация прошла успешно?
Rsync возвращает код завершения 0 при успехе и ненулевой при ошибке. В скриптах: if rsync -av ... ; then echo "OK"; else echo "FAILED"; fi. Также смотрите последние строки вывода — rsync всегда выводит сводку с числом переданных файлов и объёмом данных.
Чем rsync отличается от scp?
scp копирует файл целиком при каждом запуске. Rsync передаёт только изменения — это принципиально быстрее при повторных копированиях. Rsync также умеет синхронизировать директории, исключать файлы, удалять лишнее в назначении и делать инкрементальные бэкапы. scp удобен для разовой передачи одного файла, rsync — для регулярной синхронизации.
Rsync по SSH — стандартный способ переносить данные между VPS. На UFO.Hosting каждый сервер доступен по SSH с момента создания, так что rsync начнёт работать сразу — без дополнительной настройки.
Похожее
Все статьи
Gitea: установка собственного Git-сервера на VPS
Gitea — самостоятельно размещаемый Git-сервис с веб-интерфейсом, похожим на GitHub. Работает на 150-200 МБ RAM, запускается через Docker за несколько минут и даёт полный контроль над кодом: приватные репозитории, pull requests, issues, CI/CD через Gitea Actions. Данные хранятся на вашем…
Iptables: базовый файрвол на Ubuntu без риска потерять доступ
Iptables — стандартный инструмент управления файрволом в Linux, который фильтрует трафик по правилам в цепочках INPUT, OUTPUT и FORWARD. Главная опасность при настройке на удалённом VPS — заблокировать собственный SSH-доступ неправильным порядком правил. Эта статья построена так, чтобы этого не…