Symlink-деплой решает проблему даунтайма при обновлении сайта. Вместо копирования файлов в рабочую директорию (что создаёт окно когда сайт частично обновлён), rsync загружает новую версию в отдельную папку releases/20260524-1200/, а затем ln -sfn переключает символическую ссылку current/ на новую папку. Операция атомарна — nginx мгновенно видит либо старую, либо новую версию целиком. Пользователи не замечают обновления.
Как устроен symlink-деплой
├── current → releases/20260524-1200/ ← nginx смотрит сюда
├── releases/
│ ├── 20260522-0930/
│ ├── 20260523-1445/
│ └── 20260524-1200/ ← новая версия
└── shared/ ← общие файлы (логи, загрузки)
Rsync загружает новую версию
rsync -az --delete dist/ user@vps:/var/www/site/releases/20260524-1200/ — файлы загружаются в отдельную папку. Сайт продолжает работать со старой версией.
Symlink атомарно переключает
ln -sfn releases/20260524-1200 current — nginx мгновенно видит новую версию. 0.1 секунды, 0 downtime.
Health-check подтверждает
curl проверяет что сайт отвечает 200. Если ошибка — symlink возвращается к предыдущей версии за 0.1 сек.
Старые версии — ротация
Хранится 10 последних версий. Старше 10 — удаляются. Любую можно восстановить за 0.1 сек.
Сравнение с другими подходами
FAQ
Что будет если symlink переключится на битую сборку?
Health-check после переключения проверяет главную страницу. Если она возвращает не 200 — symlink возвращается к предыдущей версии. Пользователи даже не замечают. GitHub CMS дополнительно валидирует билд до rsync — битые сборки не попадают на сервер.
Сколько места занимают 10 версий сайта?
Статический сайт из 50-100 страниц — 5-15 MB на версию. 10 версий = 50-150 MB. На VPS с 20 GB диска это незаметно. Старые версии ротируются автоматически.
Деплойте с 0 downtime уже сегодня
GitHub CMS Pro — symlink-деплой настроен из коробки. Git push → 2 минуты → production с 0 downtime.