Когда нужно перенести сайт на новый сервер, сделать копию папки с данными или каждую ночь отправлять резервную копию на другой сервер, обычного cp уже не хватает. Для таких задач в Linux есть rsync. Он копирует файлы и локально, и по сети через SSH, а при повторном запуске передаёт только то, что изменилось. В этой статье разберём, как rsync решает, что копировать, научимся пользоваться основными параметрами и избежим двух ошибок, из-за которых данные оказываются не там или исчезают совсем. Все команды мы проверили на тестовом сервере с Debian 12.
Почему rsync, а не cp
Команда cp при каждом запуске копирует всё, что ей указали, независимо от того, что уже лежит в папке назначения. Для разового копирования это не проблема, но если папка весит десятки гигабайт, а изменилась в ней пара файлов, повторное копирование всего объёма займёт много времени и, если речь о другом сервере, всю пропускную способность канала. rsync устроен иначе. Перед тем как что-то передать, он сравнивает список файлов в источнике и в месте назначения. По умолчанию файл считается неизменившимся, если у него совпадают размер и время последнего изменения, и такой файл пропускается целиком.
Изменившиеся файлы rsync тоже не всегда передаёт полностью. Если старая версия файла уже есть на другой стороне, принимающая сторона разбивает её на блоки и отправляет их контрольные суммы. Передающая сторона ищет совпадающие блоки в новой версии файла и пересылает только то, что не совпало, а принимающая собирает новый файл из своих старых блоков и полученных кусочков. Для большого файла, в который дописали несколько строк, по сети уходит совсем немного. На тестовом сервере мы скопировали папку размером 8,2 МБ, затем дописали строку в один файл и запустили ту же команду снова. Во второй раз rsync передал только этот файл и отправил чуть больше килобайта.
Чтобы копия была точной, rsync умеет сохранять права доступа, владельца, время изменения и символические ссылки. Для этого почти всегда используют параметр -a, архивный режим, который включает всё это разом. А по сети rsync работает поверх SSH. Отдельная служба на сервере не нужна, достаточно, чтобы сама программа rsync была установлена на обеих сторонах и вы могли подключиться к серверу по SSH.
Что понадобится
rsync на обоих серверах. В нашем образе Debian 12 его по умолчанию нет. Установите его командой ниже на каждом сервере, который участвует в копировании.
bashapt install -y rsyncДоступ по SSH ко второму серверу, если копируете по сети.
1. Скопируйте папку на этом же сервере
rsync -avh /srv/site/ /backup/site/-aархивный режим, сохраняет права, владельца, время и ссылки, а папки копирует целиком.-vвыводит список копируемых файлов.-hпоказывает размеры в понятном виде, например8.21M.
Запустите ту же команду ещё раз после изменения файлов, и rsync передаст только изменившееся.

Второй запуск передал один изменённый файл вместо всей папки
2. Запомните правило косой черты
Косая черта в конце пути источника меняет результат. Без неё rsync копирует саму папку, с ней только её содержимое.
# Внутри /tmp/t1 появится папка site
rsync -a /srv/site /tmp/t1/
# В /tmp/t2 окажутся файлы и папки из site
rsync -a /srv/site/ /tmp/t2/
Без косой черты внутри появилась папка site, с ней только содержимое
Самый надёжный способ не путаться в этом правиле это всегда ставить косую черту в конце обоих путей, если нужно синхронизировать содержимое одной папки с содержимым другой.
3. Скопируйте файлы на другой сервер
Адрес удалённого сервера записывается как пользователь@IP:/путь. Параметр -z сжимает данные при передаче, а --progress показывает ход копирования каждого файла.
# С этого сервера на другой
rsync -avzh --progress /srv/site/ root@IP-адрес-сервера:/var/www/site/
# С другого сервера на этот
rsync -avzh --progress root@IP-адрес-сервера:/var/www/site/ /srv/site/Если SSH на втором сервере работает не на порту 22 или вход выполняется по ключу из нестандартного файла, передайте параметры SSH через -e.
rsync -avzh -e "ssh -p 2222 -i ~/.ssh/my_key" /srv/site/ root@IP-адрес-сервера:/var/www/site/Ненужные файлы можно исключить параметром --exclude. Путь в нём указывается относительно источника.
rsync -avzh --exclude "logs/" --exclude "*.tmp" /srv/site/ root@IP-адрес-сервера:/var/www/site/Для проверки мы отправили папку по SSH на этот же сервер, исключив папку с логами. Для настоящего переноса вместо 127.0.0.1 указывается IP-адрес второго сервера.

Файлы переданы по SSH, папка logs исключена
4. Сделайте точную копию с --delete
По умолчанию rsync только добавляет и обновляет файлы, но не удаляет в месте назначения те, которых больше нет в источнике. Чтобы копия стала точным зеркалом, добавляют --delete. Это самый опасный параметр rsync, поэтому сначала запускайте команду в пробном режиме с параметром -n. Он покажет всё, что будет сделано, но ничего не изменит.
# Пробный запуск, ничего не меняет
rsync -avhn --delete /srv/site/ /backup/site/
# Если в списке только то, что действительно нужно удалить, запустите без -n
rsync -avh --delete /srv/site/ /backup/site/
Строки deleting показывают, что будет удалено, DRY RUN означает, что ничего не тронуто
Не перепутайте источник и назначение
Если в команде с --delete поменять местами пути, rsync сделает «зеркалом» не копию, а оригинал и удалит в нём всё, чего нет в копии. Всегда сначала запускайте такую команду с -n.
Как перенести сайт на новый VPS
rsync удобен для переезда, потому что второй запуск передаёт только то, что изменилось за время первого.
Установите rsync на обоих серверах и проверьте, что со старого сервера можно подключиться к новому по SSH.
Скопируйте файлы сайта на новый сервер, пока старый ещё работает.
bashrsync -avzh --progress /var/www/site/ root@IP-нового-сервера:/var/www/site/Перенесите базу данных отдельно, например дампом, и настройте на новом сервере веб-сервер.
Перед переключением повторите команду из шага 2. На этот раз она передаст только файлы, изменившиеся за время переезда.
Направьте домен на новый сервер, как описано в статье про привязку домена.
Для регулярных резервных копий ту же команду rsync можно запускать по расписанию через cron.
Частые вопросы
bash: rsync: command not found
rsync не установлен на одной из сторон. Мы получили эту ошибку, когда копировали на сервер, где rsync ещё не был установлен. В ответ удалённая сторона пишет bash: line 1: rsync: command not found, а локальная сообщает, что соединение неожиданно закрылось. Установите rsync командой apt install -y rsync на обоих серверах.
Файлы оказались в лишней вложенной папке
В конце пути источника не было косой черты, поэтому rsync скопировал саму папку внутрь места назначения. Перенесите содержимое на уровень выше или повторите копирование с путём, который заканчивается на /.
Как скопировать, не перезаписывая более новые файлы на другой стороне
Добавьте параметр -u. Тогда rsync пропустит файлы, которые в месте назначения новее, чем в источнике.
Наши ресурсы
Telegram-канал: https://t.me/f3cloud_news
Официальный сайт: https://f3cloud.com