---
date: 2026-04-17
type: decision
tags: [nextcloud, sync, gitea, rclone, infrastructure]
---

# Синхронизация knowledge-base: Gitea + Nextcloud через rclone bisync

## Контекст

Vault `~/knowledge-base` хранился только в Gitea (`git.dttb.ru/oleg/knowledge-base.git`). Требования к надёжности и удобству:
- доступ с мобильного (iPhone Obsidian)
- мгновенная копия между устройствами без ручного `git pull/push`
- резервирование на случай проблем с git-историей

На dttb.ru развёрнут **Nextcloud AIO 32.0.6** (VM 250, 10.0.0.230:11001, NPM на `dttb.ru`). Ещё в феврале 2026 была создана папка `/Knowledge Base/` и односторонний скрипт `sync-kb-to-nextcloud.sh` на LXC 129 (Clawdbot) — но LXC 129 с тех пор удалён, скрипт не работает.

## Варианты

1. **Оставить только Gitea** — надёжно, но мобильный доступ через obsidian-git тормозной
2. **Перенести основу в Nextcloud** — хорошо для sync, но потеря git-истории
3. **Gitea основа + Nextcloud зеркало через GUI Nextcloud.app** — классика, real-time, но GUI wizard сложно автоматизировать
4. **Gitea основа + Nextcloud зеркало через rclone bisync + hook** — CLI-only, триггерится после Claude-сессий
5. **nextcloudcmd + launchd каждые 60 сек** — пробовал, **не работает**: Qt из launchd-контекста macOS получает `Host unreachable` хотя curl/ping в том же процессе работают. Специфика macOS 26 для background-агентов, обходить не смог.

## Решение

**Вариант 4 (CLI rclone bisync + Claude Code Stop-hook)** с опциональным добавлением GUI Nextcloud.app позже.

### Архитектура

```
        iPhone Obsidian / Nextcloud клиенты
         ↕  HTTPS WebDAV
   Nextcloud dttb.ru (VM 250)
         ↕  Apple File Provider API (macOS 26+)
   ~/Library/CloudStorage/Nextcloud-admin@dttb․ru/Knowledge Base/
         ↕  rclone bisync LOCAL↔LOCAL (launchd каждые 60 сек)
   ~/knowledge-base/   ◄── primary workspace
         │  git push/pull + obsidian-git autoPush (5 мин)
         ▼
   Gitea (git.dttb.ru)  ◄── source of truth для серверных клиентов
         │
         ├─► code-server LXC 132 /root/knowledge-base
         │      cron */5: kb-autosync.sh (pull + auto-commit + push)
         │
         └─► openclaw LXC 137 /root/knowledge-base  (READ-ONLY)
                cron */15: kb-pull.sh (pull --ff-only only)
```

### Ключевая находка: local-to-local bisync через launchd

Первая попытка была rclone bisync ↔ WebDAV через launchd — падала с `Host unreachable` (Go из launchd-контекста macOS не может коннектиться на LAN). Обход:
1. Nextcloud.app настроен через webflow OAuth на admin@dttb.ru
2. macOS File Provider (native Apple API, не Qt) зеркалит весь `admin@dttb.ru` в `~/Library/CloudStorage/Nextcloud-admin@dttb․ru/`
3. rclone bisync теперь работает **между двумя локальными путями** — без network-syscalls, launchd-проблема обойдена
4. File Provider сам делает upload/download в Nextcloud (Apple-подписан, имеет полный network context)

**Задержка:** iPhone → Mac vault ≈ File Provider (10-30с) + rclone launchd (≤60с) ≈ 90 сек max.

### Расширение на серверы (2026-04-17)

| Хост | Путь | Режим | Триггер | Скрипт |
|------|------|-------|---------|--------|
| Mac | `~/knowledge-base` | RW, git + rclone+NC | Stop-hook Claude, ручной | `~/.config/nextcloud-kb/sync.sh` |
| code-server LXC 132 | `/root/knowledge-base` | RW git | cron `*/5 * * * *` | `/usr/local/bin/kb-autosync.sh` |
| openclaw LXC 137 | `/root/knowledge-base` | **RO git** (push disabled) | cron `*/15 * * * *` | `/usr/local/bin/kb-pull.sh` |

**openclaw read-only** через `git remote set-url --push origin DISABLED_READONLY` — любая попытка push из бота завершится ошибкой "Could not resolve host", случайно перезаписать не сможет.

### Нормализация на code-server (2026-05-26)

Обнаружено что на LXC 132 параллельно существовали **два независимых клона** одного репо:
- `/root/knowledge-base/` — рабочий, `git.dttb.ru` remote, обслуживался `kb-autosync.sh` cron'ом
- `/root/.claude/knowledge-base/` — отдельный клон, `10.0.0.189:3000` remote, использовался Claude Code и Obsidian, **отстал от remote на 1.5 месяца (239 коммитов)**

При попытке push с Claude-клона: rebase-каскад на сотни файлов, конфликты. Это нестабильно.

**Решение:** `/root/.claude/knowledge-base/` → симлинк на `/root/knowledge-base/`. Старый клон сохранён как `/root/.claude/knowledge-base.bak-2026-05-26` (на случай если что-то нужно достать). Все процессы теперь пишут в **один git-репо**, cron каждые 5 минут реально синхронизирует то что наработал Claude Code.

Также: на LXC 136 (Gitea) сетевой настройкой стояло `ip=dhcp` — DHCP выдал `.191` вместо `.189`, push с code-server возвращал `Couldn't connect`. Заменено на `ip=10.0.0.189/24,gw=10.0.0.1` (статика).

### Компоненты

- **`/Users/ai/.config/nextcloud-kb/rclone.conf`** — WebDAV ремоут `kbsync:` на `https://dttb.ru/remote.php/dav/files/admin`, app password в obscured виде
- **`/Users/ai/.config/nextcloud-kb/rclone-filter.lst`** — исключения: `.git/**`, `.claude/worktrees/**`, `.obsidian/workspace*.json`, `.obsidian/cache/**`, `.DS_Store`, sync-метаданные
- **`/Users/ai/.config/nextcloud-kb/sync.sh`** — обёртка с atomic lock (mkdir), вызывает `rclone bisync` с retry
- **`/Users/ai/.config/nextcloud-kb/app-password`** — app password (chmod 600), получен через `POST /ocs/v2.php/core/getapppassword`
- **Hook в `~/.claude/settings.json`** — Stop-event триггер, `async: true`, запускает sync.sh если cwd в ~/knowledge-base

### Почему rclone а не nextcloudcmd

- nextcloudcmd (Qt) падает с `Host unreachable` при запуске из launchd-агента
- rclone (Go) работает в CLI, двусторонний `bisync` с state-файлами
- Проще retry-логика, log-файл, exit-коды

### Почему не nextcloudcmd + launchd-агент

Внутри launchd-процесса macOS 26:
- curl/nc/ping успешно коннектятся к 10.0.0.195:443
- Go и Qt runtime получают `EHOSTUNREACH` на тот же IP
- Не DNS, не firewall, не IPv6 — глубокая специфика network-context для background-агентов
- Решение: не запускать из launchd, а триггерить из user-session (Stop-hook = user-session)

### Для real-time sync (будущее, опционально)

GUI Nextcloud.app запускается в Aqua-session (не launchd), работает без этих проблем. Настройка через wizard, 6 кликов. На данный момент отложено.

## Последствия

### Что обновить
- [x] `credentials.md` — добавить Nextcloud creds, убрать ссылки на LXC 129/10.0.0.206
- [x] `projects/dttb/proxmox-inventory.md` — актуализировать список LXC (129, 133 больше нет)
- [x] `CLAUDE.md` (vault) — убрать упоминание LXC 129 Clawdbot если есть
- [x] `claude-memory/MEMORY.md` — обновить reference_infra, убрать LXC 133

### Что надо помнить
- Изменения локально → Nextcloud автоматом **только** после завершения Claude-сессии в `~/knowledge-base`, или ручным запуском `~/.config/nextcloud-kb/sync.sh`
- Изменения с другого устройства → подтянутся следующим запуском sync.sh (не автоматом)
- Для real-time надо доделать GUI Nextcloud.app wizard
- `.git/` **не** в Nextcloud — git и nextcloud параллельные каналы, не вложенные

### Файлы экосистемы

**На Mac:**
```
~/.config/nextcloud-kb/
├── app-password                  chmod 600 (для WebDAV ручного sync.sh)
├── rclone.conf                   chmod 600
├── rclone-filter.lst
├── sync.sh                       chmod 700 (WebDAV bisync — ручной + Stop-hook)
├── sync-local.sh                 chmod 700 (local bisync — через launchd)
├── sync.log, sync-local.log      логи
├── rclone.log, rclone-local.log  подробные rclone логи
└── sync.lock.d/ sync-local.lock.d/   atomic locks

~/Library/LaunchAgents/ru.dttb.kb-sync-local.plist   StartInterval=60s
```

**На code-server (LXC 132):**
```
/root/knowledge-base/          полный RW git-клон
/usr/local/bin/kb-autosync.sh  cron-скрипт */5
/var/log/kb-autosync.log       логи
/tmp/kb-autosync.lock          flock
```

**На openclaw (LXC 137):**
```
/root/knowledge-base/          RO git-клон (push disabled)
/usr/local/bin/kb-pull.sh      cron-скрипт */15
/var/log/kb-pull.log           логи
```

### Сквозной тест 2026-04-17 (пройден)
- Mac создаёт файл → `git push` → code-server `kb-autosync.sh` fast-forward через 0-5 мин → openclaw `kb-pull.sh` ff-only через 0-15 мин ✓
- code-server создаёт файл → auto-commit + push → Mac `git pull` подтягивает ✓
- Mac удаляет файл → push → обе LXC удаляют у себя при следующем sync ✓

### Credentials Nextcloud (dttb.ru)
- URL: `https://dttb.ru`
- User: `admin` / пароль `1qaz!QAZ`
- App password (для sync): хранится в `~/.config/nextcloud-kb/app-password`
- WebDAV: `https://dttb.ru/remote.php/dav/files/admin/Knowledge Base/`
- Сервер: Nextcloud AIO 32.0.6 на VM 250 (10.0.0.230:11001)

### Откат
- Остановить sync: удалить hook из `~/.claude/settings.json` + `rm -rf ~/.config/nextcloud-kb/`
- Удалить app password на сервере: User settings → Security → Devices/sessions
- Локальный vault не страдает — git remote и работает независимо
