Установка
Вопрос, на который здесь есть ответ: что и куда я ставлю, и где на самом деле живут разговоры?
Общая форма
Заголовок раздела «Общая форма»Каждая машина запускает весь продукт и хранит собственную копию журнала событий. Одна из них - дом (home); остальные - клиенты. Клиент отправляет то, что записал, домой и слушает всё остальное; дом раздаёт дальше.
Дом - не мастер. Он хранит тот же подписанный журнал, что и все остальные; если он сгорит, на каждой машине останется весь разговор, и любая из них может стать домом сменой одной настройки. Он существует потому, что до закрытого ноутбука не достучаться, а два ноутбука, никогда не открытые одновременно, никогда не сойдутся.
Машина, у которой не настроен адрес дома, и есть дом. Это же и случай одной машины: свежая установка разговаривает сама с собой и не требует никакой настройки.
Как машины достигают друг друга
Заголовок раздела «Как машины достигают друг друга»Четыре схемы; разница в том, какая машина может дозвониться до какой. Выберите одну в Settings → Relay на доме; каждая другая машина считает выбор из журнала.
| Что это | Нужен секрет | |
|---|---|---|
| Одна локальная сеть | Все машины в одном здании. Ничего не ставить; ничего не работает вне этой сети. | Нет |
| Tailscale | Каждая машина получает адрес, работающий откуда угодно, за любым NAT. | Нет - tailnet приватна |
| Одна постоянно включённая машина дома | Вариант по умолчанию. Клиенты дозваниваются, где бы они ни были. | Нет |
| Дом на публичном адресе | VPS или порт, проброшенный на машину дома. | Да - настройка отказывает без него |
Клиент только дозванивается наружу, поэтому машина за carrier NAT или за хотспотом
уже сегодня работает как клиент; она просто не может быть той машиной, до которой дозваниваются
все. Публичный адрес - тот, к которому может присоединиться интернет - сначала задайте
MAVEN_TEAMS_SECRET одинаковой строкой на каждой машине. Это не шифрование; оно покупает ровно
одно свойство - посторонний не сможет присоединиться. Задайте его везде за один присест:
отказ здесь тихий.
1 · Установка на каждой машине
Заголовок раздела «1 · Установка на каждой машине»Node 22.22+ (ради node:sqlite), git, POSIX-shell.
git clone <your-repository-url> ~/maven-teamscd ~/maven-teamsnpm cinpm run buildnpm start # http://localhost:3400Скопируйте .env.example в .env.local и заполните ключи, которые у вас есть; все они
опциональны. Переменные, которые решают, как машина ведёт себя в сети:
| Переменная | Что делает |
|---|---|
MAVEN_STATE_DIR |
Где живут журнал, ключ подписи, настройки и задачи. По умолчанию ~/.maven-teams - намеренно не ~/.maven M.A.V.E.N, с которым у неё семнадцать общих имён файлов. |
MAVEN_MACHINE |
Имя этой машины в журнале и в каждой строке аудита. По умолчанию - hostname. |
MAVEN_HOME_URL |
Адрес дома. Задайте - и эта машина клиент; оставьте пустым - и она дом. Settings → Relay тоже может задать его, без перезапуска; если есть и то и другое, побеждает переменная. |
MAVEN_TEAMS_SECRET |
Общий секрет рабочего пространства. Отсутствует - значит открыто: правильно за роутером, неправильно на публичном адресе. |
MAVEN_FORCE_CLOUD |
1 отправляет каждую возможность к провайдеру независимо от железа. См. Вычисления. |
PORT / HOST |
По умолчанию 3000 / 127.0.0.1; служба задаёт 3400. Машине, до которой должны достучаться другие, нужен HOST=0.0.0.0. |
Та, что выглядит как сбой сети
Заголовок раздела «Та, что выглядит как сбой сети»Объявляемый адрес машины читается из её сетевого интерфейса; а то, на чём она слушает, -
это HOST. Оставьте значение по умолчанию - и машина уверенно опубликует
http://192.168.1.42:3400, принимая при этом только соединения от самой себя: как клиент
она работает идеально, домом быть не может никогда, и каждый экран говорит, что всё хорошо.
Environment=HOST=0.0.0.0Environment=PORT=3400Постоянный запуск
Заголовок раздела «Постоянный запуск»Пользовательская служба systemd - чтобы она работала от вашего имени и могла читать ваши ключи:
[Unit]Description=MAVEN TeamsAfter=network-online.target
[Service]WorkingDirectory=%h/maven-teamsEnvironment=NODE_ENV=productionEnvironment=PORT=3400Environment=MAVEN_MACHINE=%HExecStart=/usr/bin/npm run startRestart=always
[Install]WantedBy=default.targetsystemctl --user daemon-reloadsystemctl --user enable --now maven-teamsloginctl enable-linger "$USER" # or it stops when you log out2 · Направьте клиентов на дом
Заголовок раздела «2 · Направьте клиентов на дом»На доме откройте Settings → Relay. Под первой строкой - «reach me at» - адреса, которые может использовать другая машина, порт уже подставлен. Скопируйте один. На каждом клиенте вставьте его в поле дома и нажмите SET HOME. Через несколько секунд панель скажет connected, и вся история рабочего пространства приедет.
Чтобы позже перенести дом, нажмите MAKE THIS MACHINE THE HOME на новой машине и задайте её адрес на остальных. Ничего не теряется: журнал уже есть на каждой машине.
Если клиент не может достучаться до дома, проверьте то направление, которое важно - с клиента:
curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 http://<home-address>:3400/api/relay200 означает, что с сетью всё в порядке и проблема в конфигурации. Для сетей, которые
не видят друг друга, поставьте машины на WireGuard или Tailscale и используйте тот адрес;
каждая машина объявляет все адреса, какие у неё есть.
3 · Проверьте, что получилось
Заголовок раздела «3 · Проверьте, что получилось»curl -s localhost:3400/api/relay | jq '{me: .me.machine, role: .hub.role, connected: .hub.connected}'curl -s localhost:3400/api/events/verify | jqЦепочка каждой машины проверяется отдельно; ok: false называет порядковый номер,
на котором разрыв.
Где что живёт
Заголовок раздела «Где что живёт»$MAVEN_STATE_DIR/ (defaults to ~/.maven-teams)├── events/│ ├── log.jsonl this machine's own chain - the one it signs│ └── peers/<machine>.jsonl one file per machine, exactly as received├── teams/│ ├── identity.json this machine's keypair. BACK THIS UP.│ ├── peers.json addresses of machines to pull from directly│ └── hub.json the home's address, if this machine is a client└── index.db SQLite full-text index - derived, delete it freelyidentity.json - единственный незаменимый файл. Потеряете его - машина не сможет
подписывать новые события; новая идентичность означает новую цепочку под тем же именем.
index.db можно выбросить - если поиск ведёт себя странно, удалите его.
Разговоры, которые вы очищаете, также записываются в ваше хранилище (vault) Obsidian
как Markdown в memories/channels/<room>/.
Что передаётся, а что нет
Заголовок раздела «Что передаётся, а что нет»Журнал несёт то, что произошло: сообщения, патчи, прогоны, согласования, решения. Он
не несёт ваши ключи - .env.local остаётся на машине, где был написан, а агенты
работают на той машине, за которой вы сидите, с вашими учётными данными. Приватный канал
скрыт, а не зашифрован: журнал реплицируется повсюду; настройка решает, что
показывает интерфейс.
См. также
Заголовок раздела «См. также»- Развёртывание в Proxmox - headless-контейнер без GPU.
- Вычисления (Local / Cloud)