Каталог Поиск 0 Сравнить 0 Закладки 0 Корзина Войти
Каталог
105082, Москва, ул. Фридриха Энгельса, 75с21, БЦ Бауманский ИТКОЛ
Пн - Пт: с 09-00 до 18-00 Сб: с 10-00 до 18-00 Вс: выходной
Страницы: 1 2 След.
RSS
Локальное резервное копирование больше недоступно? Обновитесь до self-hosted Unifi OS Server 5.0.6, UniFi Network
 
Уважаемые участники сообщества, раньше я запускал UniFi Network Application в Docker, используя образ Linuxserver.io. В графическом интерфейсе я мог настроить автоматическое резервное копирование по ночам. Затем я использовал простой скрипт, чтобы копировать эти резервные копии с хоста на свой NAS. Я добавил скрипт в crontab, и всё работало идеально. Недавно начали появляться всплывающие окна с сообщением, что мне нужно перейти на новую "UniFi OS Server", поэтому я удалил контейнер и установил UniFi OS Server на свой хост с Ubuntu, следуя официальной инструкции по установке. Я восстановил резервную копию, и всё работает отлично. Сейчас у меня консоль версии 5.0.6 и версия приложения 10.1.84 (Network). Однако я больше не могу настроить автоматическое резервное копирование. В графическом интерфейсе есть только возможность вручную скачать файл резервной копии. Я не хочу привязывать свой UniFi OS Server к облаку, поэтому автоматическое облачное резервное копирование мне не подходит. Есть ли возможность создать резервную копию (.unf) вручную через командную строку или CLI? Если да, я мог бы написать скрипт и снова иметь ежедневное резервное копирование, копируемое на мой NAS. С уважением, Бак Бэгген
 
О, круто! Обязательно попробую — сэкономлю ещё один контейнер. К тому же у меня иногда бывают таймауты, так что сразу пойму, в чём проблема: в моём сервере Unifi OS или в решении на Playwright. Спасибо!
 
Пока Playwright у всех вас вроде работает, для меня это было слишком громоздко ради двух мелких HTTP-запросов. Поэтому я написал простой скрипт, который автоматически скачивает бэкапы в headless-режиме. В нём ещё есть простая настраиваемая ротация бэкапов. Репозиторий со скриптом и инструкцией по настройке: gitlab(dot)com/faerbit/uos-backup
 
Я протестировал это дальше, и пока всё работает идеально! Я добавил эту строку в начало скрипта, после 'import requests':
import warnings
warnings.filterwarnings("ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning)
Таким образом, я не получаю предупреждения SSL — только нужный вывод от скрипта. Затем я добавил это в crontab -e с уведомлением по email (разумеется, для этого у вас должен быть настроен SMTP на вашем хосте):
# Backup UniFi OS server script
15 0 * * * cd /mnt/scripts && OUTPUT=$(/usr/bin/python3 uos-backup.py 2>&1); ( echo "From: Noreply | IT Buck <mail@domain.com>"; echo "To: mail@domain.com"; echo "Reply-To: mail@domain.com"; echo "Subject: UOS Backup Script Output"; echo "Date: $(date -R)"; echo; echo "$OUTPUT" ) | msmtp -t
Так что я использую только скрипт 'uos-backup.py', а не 'uos-backup.service' или 'uos-backup.timer'. Спасибо и респект faerbit -> gitlab(dot)com/faerbit/uos-backup Теперь мне просто нужно протестировать это на длительном сроке, чтобы увидеть, останется ли он стабильным. Опция Playwright часто вызывала таймауты — иногда он работал днями, а иногда выходил из строя несколько дней подряд. Мне интересно, сработает ли это решение лучше (так как я не уверен, была ли проблема в Playwright или в самом сервере UniFi OS).
 
Класс, работает идеально! Спасибо!
 
I failed to push my latest commit with the option to replace ":" with ".". It should be there now.
 
Я перепроверил — и ты прав! Проблема не в длине имени файла, а только в двоеточиях. Я использовал исходный скрипт из твоего GitLab и создал резервную копию. При доступе через SMB с macOS или Windows я всё ещё вижу эти странные имена файлов. Однако через Ubuntu (NFS) или напрямую на NAS имена файлов отображаются корректно. Поэтому я заменил двоеточия на точки в именах файлов на NAS, и после этого файлы тоже стали правильно отображаться через SMB с macOS и Windows. Я продолжу использовать исходный скрипт (так что мне не нужно укорачивать имена файлов в итоге), но хотел бы иметь возможность избегать двоеточий в именах файлов. Не мог бы ты добавить такую опцию в исходный скрипт на своём GitLab, или это можно легко сделать самому? (Без укорачивания имени — это не обязательно, как ты и сказал.)
 
I added an option to replace ":" with ".". Your length limitations sound quite insane, and some googling didn't confirm that the files are actually too long, so I don't want to add that to the repo. However here is the diff which achieves what you want:diff --git a/uos-backup.py b/uos-backup.py
index db1aa07..bc94801 100644
--- a/uos-backup.py
+++ b/uos-backup.py
@@ -61,7 +61,7 @@ def download():
    if CONVERT_TIMESTAMP_HUMAN_READABLE:
        file_ts, filename_end = extract_file_ts(filename)
        file_ts = datetime.fromtimestamp(int(file_ts) / 1000)
-        filename = f"{BACKUP_FILE_NAME_PREFIX}{file_ts.isoformat(timespec='seconds')}_{filename_end}"
+        filename = f"{BACKUP_FILE_NAME_PREFIX}{file_ts.isoformat(timespec='seconds')}.unifi"
        if INCOMPETENT_FILE_SYSTEM:
            filename = filename.replace(":", ".")
    print(f"downloaded \"{filename}\"")
 
Пока что меня это не подводило, и я основательно гонял эту штуку во время тестирования. Но полезно знать об этом на случай, если вдруг начнутся сбои.
 
Честно говоря, я сначала пошёл по пути использования API, но оно чаще всего не срабатывало, поэтому я перешёл на Playwright. Вариант прямого вызова API оказался ненадёжным.
 
Ошибка действительно была вызвана другими бекапами в папке, которые не были созданы скриптом. Я использовал пустую папку, и теперь всё работает без ошибок. Причина, по которой мой MacBook так странно отображает имена файлов, в том, что они слишком длинные — SMB с этим плохо справляется. Та же проблема возникает, когда я подключаюсь по SMB с Windows-машины. С NFS имена файлов отображаются корректно. Не могли бы вы подправить скрипт, чтобы имена файлов были короче и не содержали двоеточий? Тогда SMB будет их нормально обрабатывать. Например: unifi_os_backup_2026-04-11T19-46-54.unifi вместо unifi_os_backup_2026-04-11T19:46:54_bfd465f3-ff54-4ea9-90dc-364d34306eb4.unifi. Я пытался изменить это сам, но это вызвало ошибки в процессе очистки скрипта (я не силён в скриптах...).
 
Я немного расширил скрипт, чтобы во время очистки просто пропускать все файлы, которые не начинаются с unifi_os_backup_. Это может помочь и тебе. Однако, поскольку я не совсем уверен, откуда берутся твои файлы, я не вполне понимаю, в чём твоя проблема.
 
Очищающая часть скрипта может работать только с теми файлами, которые сама туда поместила. Если у тебя там лежат файлы с названиями типа UOR3KA~U или похожими, логично, что скрипт на них споткнётся. Попробуй просто удалить их и посмотреть, заработает ли. Если они продолжают появляться из-за какой-то странной SMB-взаимодействия, возможно, стоит настроить папку для бэкапов на локальном хранилище, а потом синхронизировать её на SMB-шару через rsync (с опцией --delete).
 
Хочу запустить скрипт вручную, чтобы протестировать его, а потом добавить в crontab с уведомлением по email. Однако при ручном запуске получаю такие сообщения об ошибках (см. ниже). Тем не менее файл сохраняется, но с именем вроде: unifi_os_backup_2026-04-11T19:39:21_f79c3381-0697-48e1-8693-de72a0552f4a.unifi. А на моём MacBook эти файлы (когда я захожу в общую папку SMB, где хранятся бекапы) отображаются как: UOR3KA~U. Есть идеи? root@dockerbeast:/mnt/scripts# ./uos-backup.py  
logging in  
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:1100: InsecureRequestWarning: Unverified HTTPS request is being made to host '10.0.1.12'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings  
 warnings.warn(  
logged in  
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:1100: InsecureRequestWarning: Unverified HTTPS request is being made to host '10.0.1.12'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings  
 warnings.warn(  
downloaded "unifi_os_backup_2026-04-11T19:46:54_bfd465f3-ff54-4ea9-90dc-364d34306eb4.unifi"  
saved "unifi_os_backup_2026-04-11T19:46:54_bfd465f3-ff54-4ea9-90dc-364d34306eb4.unifi" at "/mnt/backup/unifi"  
starting clean up  
Traceback (most recent call last):  
 File "/mnt/scripts/./uos-backup.py", line 97, in <module>  
   main()  
 File "/mnt/scripts/./uos-backup.py", line 93, in main  
   cleanup()  
 File "/mnt/scripts/./uos-backup.py", line 74, in cleanup  
   file_ts, _ = extract_file_ts(b.name)  
                ^^^^^^^^^^^^^^^^^^^^^^^  
 File "/mnt/scripts/./uos-backup.py", line 39, in extract_file_ts  
   ts, e = filename.removeprefix(BACKUP_FILE_NAME_PREFIX).split("_", 1)  
           ^^^^^  
ValueError: not enough values to unpack (expected 2, got 1)
 
Уважаемые участники сообщества,  
Я настроил систему автоматического резервного копирования так, чтобы теперь также отправлялись уведомления по электронной почте.  

Я запускаю контейнер с помощью скрипта ниже:  

`#!/bin/bash`  

```bash
# Указываем имя файла для лога
LOG_DIR="/mnt/backup/unifi/logs"
LOG_FILE="$LOG_DIR/unifi_backup_$(date +'%Y-%m-%d_%H-%M-%S').log"

# Создаём папку для логов, если её нет
mkdir -p "$LOG_DIR"

# Запускаем контейнер и пишем логи в файл
docker start unifi-backup -a >> "$LOG_FILE" 2>&1
```

А в `crontab -e` я больше не запускаю контейнер напрямую — теперь вызываю скрипт, включая настройки почты:  

```
#backup unifi os server
15 0 * * * /bin/bash /mnt/scripts/run_unifi_backup.sh; LOG="/mnt/backup/unifi/logs/$(ls -1t /mnt/backup/unifi/logs | head -n 1)"; ( echo "From: displayname mail <mail@domain.com>"; echo "To: mail@domain.com"; echo "Reply-To: mail@domain.com"; echo "Subject: Unifi OS Server backup"; echo "Date: $(date -R)"; echo; echo "Logfile: $(basename "$LOG")"; echo; cat "$LOG" ) | msmtp -t
```

В строке crontab нужно подставить своё отображаемое имя отправителя и адрес электронной почты в поле From. Для To и Reply-To также укажите свои предпочтительные email-адреса.  
Разумеется, для работы этого необходимо настроить SMTP на вашем хосте.
 
Я проработал способ настройки регулярного локального резервного копирования на Synology NAS. Взял скрипт на Playwright и модифицировал его для работы с последней версией интерфейса UniFi OS и модальными окнами подтверждения загрузки, специально оптимизировав для среды Docker.Основная сложность с новыми версиями контроллера в том, что для отображения кнопок резервного копирования требуется настоящий браузер. Этот скрипт обрабатывает вход в систему, навигацию и финальный клик по загрузке внутри headless-контейнера.Скрипт (unifi_backup.js):const { chromium } = require('playwright');
const path = require('path');

/* Конфигурация берётся из переменных окружения, чтобы не хранить учётные данные в коде. */
const UNIFI_HOST = process.env.UNIFI_HOST;
const USERNAME = process.env.UNIFI_USER;
const PASSWORD = process.env.UNIFI_PASS;
const SAVE_DIR = '/backups';

function getTimestamp(forFileName = false) {
 const d = new Date();
 if (forFileName) return d.toLocaleDateString('sv-SE');
 return d.toLocaleString('sv-SE', { timeZone: 'Europe/Stockholm' });
}

(async () => {
 // Очищаем заголовки для лог-файла
 console.log('--- Starting backup ' + getTimestamp() + ' ---');

 if (!UNIFI_HOST || !USERNAME || !PASSWORD) {
   console.error('Error: Missing environment variables.');
   process.exit(1);
 }

 const browser = await chromium.launch({
   headless: true,
   args: ['--ignore-certificate-errors', '--no-sandbox']
 });

 const context = await browser.newContext({
   ignoreHTTPSErrors: true,
   acceptDownloads: true,
 });

 const page = await context.newPage();

 try {
   // Переход на страницу входа
   await page.goto(`https://${UNIFI_HOST}/login`, { waitUntil: 'networkidle' });
   
   // Заполнение учётных данных
   await page.fill('input[name="username"]', USERNAME);
   await page.fill('input[name="password"]', PASSWORD);
   await page.click('button[type="submit"]');
   await page.waitForNavigation({ waitUntil: 'networkidle' });

   // Переход к настройкам резервного копирования
   await page.goto(`https://${UNIFI_HOST}/network/default/settings/control-plane/backups`);
   await page.waitForTimeout(10000); // Ожидание рендера интерфейса

   // Поиск и клик по триггеру загрузки
   const downloadTrigger = page.locator('#backupSettings button').filter({ hasText: 'Download' });
   await downloadTrigger.waitFor({ state: 'visible' });
   
   const downloadPromise = page.waitForEvent('download');
   await downloadTrigger.dispatchEvent('click');

   // Клик по финальной кнопке подтверждения в модальном окне
   const confirmButton = page.locator('div[role="dialog"] button').filter({ hasText: 'Download' }).last();
   await confirmButton.click();

   // Сохранение файла в смонтированный том
   const download = await downloadPromise;
   const finalPath = path.join(SAVE_DIR, `unifi_backup_${getTimestamp(true)}.unf`);
   await download.saveAs(finalPath);

   console.log('Success: Backup saved.');
 } catch (err) {
   console.error('Error:', err.message);
   process.exitCode = 1;
 } finally {
   await browser.close();
   console.log('--- Finished ' + getTimestamp() + ' ---');
   process.exit(0);
 }
})();
Настройка Synology: я запускаю это как проект в Container Manager. Для автоматизации использую Планировщик заданий Synology (Панель управления) с командой docker start <имя-контейнера> ежедневно.Также добавил простую строку очистки в запланированное задание, чтобы предотвратить заполнение NAS: find /volume1/backups/unifi -name '*.unf' -type f -mtime +30 -deleteЭто очень стабильный способ гарантировать наличие локальных файлов .unf без ручного вмешательства.
 
Блин, только сегодня узнал об этом лол, такая обратная эволюция, надеюсь, они хотя бы сделают ежедневное автоматическое резервное копирование позже, я ещё скачиваю файл резервной копии и переношу его на свой локальный NAS через cron
 
Норм, молодцы!
 
Сработало! Я создал нового пользователя и сделал его владельцем. Затем смог ввести локальные данные в старый аккаунт и переключиться обратно. Теперь бекап работает :-) Огромное спасибо! Привет из Германии
 
К сожалению, это поле мне недоступно: я запускаю сервер ОС на Debian.

Думаю, это произошло из-за того, что изначально я настроил сервер только для локального доступа, без учётной записи в интерфейсе UI. После этого я включил удалённый доступ и привязал сервер к своей учётной записи UniFi.В итоге теперь у меня, видимо, есть и локальная учётка, и учётка UI.Что, по сути, мне не нужно. Я бы предпочёл только локальный доступ, но, насколько я понимаю, это уже не откатить. А так как у меня нет отдельного бэкапа Network Application, а только всей системы UniFi OS, переустановка не вариант. Как только я восстановлю бэкап — всё вернётся к тому же… а переконфигурировать всё с нуля я точно не собираюсь.Не удивлюсь, если это работает и в обратную сторону. Если изначально не настроить как локальное, потом, наверное, тоже не вернуться к локальным учёткам и паролям.Но, возможно, стоит покопаться. Через CLI или подправив конфиги, может, всё же есть способ что-то изменить.
Страницы: 1 2 След.
Читают тему (гостей: 1)