# Синхронизация `config.toml` между `mtg.ivx.su`, `gt1.ivx.su`, `gt2.ivx.su` и `gt3.ivx.su` Целевая схема: - **A (primary, запись):** `mtg.ivx.su` - **B (replica, только чтение):** `gt1.ivx.su`, `gt2.ivx.su`, `gt3.ivx.su` Изменения вносятся только на A (через API/бот), затем автоматически синхронизируются на все B. ## 1) Подготовка `telemt-data` на каждом B-сервере ```bash cd /opt/telemt-plus docker compose stop telemt mkdir -p telemt-data/cache ``` Если ранее использовались отдельные файлы рядом с compose: ```bash mkdir -p backup-telemt-$(date +%F-%H%M%S) cp -a config.toml proxy-secret cache docker-compose.yml backup-telemt-$(date +%F-%H%M%S)/ 2>/dev/null || true [ -f config.toml ] && cp -f config.toml telemt-data/config.toml [ -f proxy-secret ] && cp -f proxy-secret telemt-data/proxy-secret [ -d cache ] && cp -a cache/. telemt-data/cache/ ``` Права под пользователя контейнера Telemt (`uid/gid = 999`): ```bash chown -R 999:999 telemt-data find telemt-data -type d -exec chmod 750 {} \; find telemt-data -type f -exec chmod 640 {} \; chmod 660 telemt-data/config.toml 2>/dev/null || true chmod 770 telemt-data/cache 2>/dev/null || true ``` ## 2) Compose-настройка (A и B) Для сервиса `telemt` должен быть volume директории: ```yaml volumes: - ./telemt-data:/run/telemt ``` Убрать: - `./config.toml:/run/telemt/config.toml` - `tmpfs: /run/telemt` ## 3) Настройка API в `config.toml` ### A (`mtg.ivx.su`) ```toml [server.api] enabled = true read_only = false ``` ### B (`gt1.ivx.su`, `gt2.ivx.su`, `gt3.ivx.su`) ```toml [server.api] enabled = true read_only = true ``` ## 4) SSH-доступ A -> B без пароля Выполняется на `mtg.ivx.su`: ```bash ssh-keygen -t ed25519 -N "" -f ~/.ssh/telemt_sync ssh-copy-id -i ~/.ssh/telemt_sync.pub root@gt1.ivx.su ssh-copy-id -i ~/.ssh/telemt_sync.pub root@gt2.ivx.su ssh-copy-id -i ~/.ssh/telemt_sync.pub root@gt3.ivx.su ssh -i ~/.ssh/telemt_sync root@gt1.ivx.su "echo ok" ssh -i ~/.ssh/telemt_sync root@gt2.ivx.su "echo ok" ssh -i ~/.ssh/telemt_sync root@gt3.ivx.su "echo ok" ``` ## 5) Установка `lsyncd` на A (`mtg.ivx.su`) ```bash apt update && apt install -y lsyncd rsync mkdir -p /etc/lsyncd ``` Создать файл `/etc/lsyncd/lsyncd.conf.lua`: ```lua settings { logfile = "/var/log/lsyncd.log", statusFile = "/var/log/lsyncd.status", nodaemon = false, } -- B1: gt1.ivx.su sync { default.rsyncssh, source = "/opt/telemt-plus/telemt-data/", host = "root@gt1.ivx.su", targetdir = "/opt/telemt-plus/telemt-data/", delay = 1, exclude = { "cache/" }, rsync = { archive = true, compress = true, _extra = { "--delete", "--chown=65532:65532", "--chmod=Du=rwx,Dg=rx,Do=,Fu=rw,Fg=r,Fo=", "-e", "ssh -i /root/.ssh/telemt_sync -o StrictHostKeyChecking=accept-new" } } } -- B2: gt2.ivx.su sync { default.rsyncssh, source = "/opt/telemt-plus/telemt-data/", host = "root@gt2.ivx.su", targetdir = "/opt/telemt-plus/telemt-data/", delay = 1, exclude = { "cache/" }, rsync = { archive = true, compress = true, _extra = { "--delete", "--chown=65532:65532", "--chmod=Du=rwx,Dg=rx,Do=,Fu=rw,Fg=r,Fo=", "-e", "ssh -i /root/.ssh/telemt_sync -o StrictHostKeyChecking=accept-new" } } } -- B3: gt3.ivx.su sync { default.rsyncssh, source = "/opt/telemt-plus/telemt-data/", host = "root@gt3.ivx.su", targetdir = "/opt/telemt-plus/telemt-data/", delay = 1, exclude = { "cache/" }, rsync = { archive = true, compress = true, _extra = { "--delete", "--chown=65532:65532", "--chmod=Du=rwx,Dg=rx,Do=,Fu=rw,Fg=r,Fo=", "-e", "ssh -i /root/.ssh/telemt_sync -o StrictHostKeyChecking=accept-new" } } } ``` ## 6) Первичная синхронизация (один раз) **Важно:** на каждом B (`gt1.ivx.su`, `gt2.ivx.su`, `gt3.ivx.su`) должен быть установлен `rsync`: ```bash # Выполнить на каждом B-сервере: apt update && apt install -y rsync ``` На `mtg.ivx.su`: ```bash # B1: gt1.ivx.su rsync -az --delete \ --chown=65532:65532 \ --chmod=Du=rwx,Dg=rx,Do=,Fu=rw,Fg=r,Fo= \ -e "ssh -i /root/.ssh/telemt_sync -o StrictHostKeyChecking=accept-new" \ /opt/telemt-plus/telemt-data/ \ root@gt1.ivx.su:/opt/telemt-plus/telemt-data/ # B2: gt2.ivx.su rsync -az --delete \ --chown=65532:65532 \ --chmod=Du=rwx,Dg=rx,Do=,Fu=rw,Fg=r,Fo= \ -e "ssh -i /root/.ssh/telemt_sync -o StrictHostKeyChecking=accept-new" \ /opt/telemt-plus/telemt-data/ \ root@gt2.ivx.su:/opt/telemt-plus/telemt-data/ # B3: gt3.ivx.su rsync -az --delete \ --chown=65532:65532 \ --chmod=Du=rwx,Dg=rx,Do=,Fu=rw,Fg=r,Fo= \ -e "ssh -i /root/.ssh/telemt_sync -o StrictHostKeyChecking=accept-new" \ /opt/telemt-plus/telemt-data/ \ root@gt3.ivx.su:/opt/telemt-plus/telemt-data/ ``` ## 7) Запуск `lsyncd` На A: ```bash systemctl enable lsyncd systemctl restart lsyncd systemctl status lsyncd --no-pager ``` Если ошибка пути конфигурации: ```bash systemctl cat lsyncd ``` ## 8) Проверка работы На каждом B (`gt1.ivx.su`, `gt2.ivx.su`, `gt3.ivx.su`): ```bash cd /opt/telemt-plus docker compose up -d --force-recreate telemt docker logs --tail=100 telemt ``` На B проверить режим read-only: ```bash curl -s http://127.0.0.1:9091/v1/health ``` В ответе ожидается `read_only: true`. ## 8.1) Перенастройка существующих B (slave) на новый `uid/gid` и повторный запуск синхронизации Если B-серверы уже были настроены со старым `--chown=999:999`, выполните эти шаги, чтобы синхронизация снова применялась корректно. 1. На A (`mtg.ivx.su`) обновить конфиг `lsyncd` и перезапустить демон (выполнять на `mtg.ivx.su` от root; желательно сначала остановить `telemt` на всех B по шагу 2, затем вставить блок целиком): ```bash sed -i.bak 's/--chown=999:999/--chown=65532:65532/g' /etc/lsyncd/lsyncd.conf.lua systemctl restart lsyncd systemctl status lsyncd --no-pager ``` 2. На каждом B (`gt1.ivx.su`, `gt2.ivx.su`, `gt3.ivx.su`) остановить `telemt` и выставить права под новый `uid/gid`: ```bash cd /opt/telemt-plus docker compose stop telemt chown -R 65532:65532 telemt-data find telemt-data -type d -exec chmod 750 {} \; find telemt-data -type f -exec chmod 640 {} \; chmod 660 telemt-data/config.toml 2>/dev/null || true chmod 770 telemt-data/cache 2>/dev/null || true ``` 3. На A выполнить повторную полную синхронизацию на все B (команды из шага 6 с `--chown=65532:65532`). 4. На A перезапустить `lsyncd`: ```bash systemctl restart lsyncd systemctl status lsyncd --no-pager ``` 5. На каждом B поднять контейнер и проверить, что узел в режиме read-only: ```bash cd /opt/telemt-plus docker compose up -d --force-recreate telemt curl -s http://127.0.0.1:9091/v1/health ``` Ожидаемо: - контейнер `telemt` стартует без ошибок прав доступа; - в health-ответе `read_only: true`; - после изменения `config.toml` на A файл автоматически обновляется на всех B. ## 9) Правило эксплуатации - Мутации (`POST/PATCH/DELETE`) делать только на A (`mtg.ivx.su`). - Бота направлять на API A. - B (`gt1.ivx.su`, `gt2.ivx.su`, `gt3.ivx.su`) держать как реплики только для чтения.