Files
knowledge-base/decisions/2026-06-08-swarmclaw-lxc135-deploy.md
2026-06-08 22:32:54 +03:00

74 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
date: 2026-06-08
type: decision
tags: [dttb, swarmclaw, openclaw, orchestrator, lxc, docker]
---
# SwarmClaw — оркестратор-надстройка над openclaw (LXC 135)
## Контекст
Олег искал «аналог openclaw — оркестратор + удобный + самообучение». По ходу выяснилось:
1. У openclaw **самообучение уже работает** (Dreaming, embeddings ready, recall с concept-tagging + spaced repetition — см. правку [[openclaw]]). Менять движок не нужно.
2. **SwarmClaw** ([github.com/swarmclawai/swarmclaw](https://github.com/swarmclawai/swarmclaw)) — это не замена, а **control-plane НАД openclaw**: рой агентов, делегирование, расписания, дашборд, и подключение существующих openclaw-gateway. Ровно «оркестратор» из запроса, без миграции стека.
Решение: поставить SwarmClaw на Proxmox (не Mac-app — тот умирает с ноутом) как постоянный дирижёр над Антошкой.
## Где живёт
| Параметр | Значение |
|----------|----------|
| Proxmox LXC | **135** (hostname `swarmclaw`) |
| IP | 10.0.0.135/24, gw 10.0.0.1 |
| ОС | Debian 12, unprivileged + `nesting=1,keyctl=1` |
| Ресурсы | 2 vCPU / 4 GB RAM / 16 GB (rootfs на `work`) |
| Рантайм | Docker 29.5 + compose, образ `ghcr.io/swarmclawai/swarmclaw:latest` |
| Каталог | `/opt/swarmclaw` (репо), данные volume `./data:/app/data` |
| Доступ | `pct exec 135 -- bash`; dashboard `http://10.0.0.135:3456` |
## Доступ к UI/API
- **URL:** `http://10.0.0.135:3456` (LAN/NetBird), слушает `0.0.0.0:3456-3457`.
- **ACCESS_KEY:** `4613e7d05f51229a96d7b1a0dd34b24e` — он же cookie `sc_auth` для API.
- Auth: `POST /api/auth {"key":"..."}` → cookie, либо header `Cookie: sc_auth=<KEY>`. `getAccessKey()=process.env.ACCESS_KEY`, `validateAccessKey` сравнивает строкой.
## Что настроено
1. **Провайдер OmniRoute** (`custom`, OpenAI-compatible):
- `baseUrl=http://10.0.0.179:20128/v1`, `requiresApiKey:false` (внутренний, отдаёт каталог без ключа).
- Каталог 58 моделей; инференс `cc/claude-opus-4-8` подтверждён (stream chat.completions).
2. **Агент «Dirizhyor»** (id `0d388a87`) — provider `omniroute`, model `cc/claude-opus-4-8`.
3. **openclaw-gateway как control-plane:**
- credential `cred_62caf5d0f0de` (provider `openclaw`, зашифрованный gateway-token).
- gateway profile `gateway-0eaf65b0` «Antoshka (openclaw 137)», endpoint `http://10.0.0.239:18789`, `isDefault:true`.
- openclaw gateway token: `20bfbdfed25b87b211a6faa60db3ab8fac75fb5100958ac8` (`gateway.auth.mode=token` на LXC 137).
- device спарен и **approved** на openclaw (`openclaw devices` → 10.0.0.135, `operator.admin`).
- connect `ok:true`.
## Грабли (важно для будущего)
1. **ACCESS_KEY жил только в `/app/.env.local` внутри контейнера** (не в volume). Пересоздание/обновление образа → новый ключ → запертый вход. **Фикс:** скопировал `ACCESS_KEY` (+`CREDENTIAL_SECRET` если будет) в **хостовый** `/opt/swarmclaw/.env.local` (он `env_file` в compose) → ключ постоянен через пересоздания. `CREDENTIAL_SECRET` дополнительно лежит в volume `data/credential-secret`.
2. **Auth rate-limit:** 5 неудачных попыток с IP → лок 15 мин (`authRateLimitMap`, in-memory). Перебор форматов auth (Bearer/x-api-key — оба неверные) триггерит. **Правильный auth — только cookie `sc_auth`.** Сброс лока — `docker compose up -d --force-recreate` (in-memory обнуляется, ключ из env_file сохраняется).
3. **Подключение openclaw требует approve device-pairing.** SwarmClaw `manualConnect` хардкодит `useDeviceAuth=true` (протокол v4, `auth:{token}` + device-signature). openclaw в token-mode создаёт **pending pairing** → пока не сделать `openclaw devices approve <requestId>` на LXC 137, connect молча `{"ok":false}`. Token-only handshake (proto4, `auth.token`, scopes `operator.admin`) проверен рабочим. После approve — connect `ok:true`, device в Paired.
4. **`/api/openclaw/doctor``spawn openclaw ENOENT`** — в контейнере нет bundled `openclaw` CLI; связь идёт по WS, не через CLI. Безвредно.
5. **DNS-FakeIP не словили** (в отличие от LXC 137): github/docker.com резолвятся честно через `1.1.1.1/8.8.8.8` даже без NetBird на 135. NetBird не ставил.
6. Локаль в LXC не настроена (`locale: Cannot set LC_*`) — косметика, при желании `locale-gen en_US.UTF-8`.
## Схема API (для будущих правок headless)
- `POST /api/providers``{id,name,baseUrl,models[],requiresApiKey,isEnabled}` (type всегда `custom`), хранит JSON в таблице `provider_configs`.
- `POST /api/agents` → zod `AgentCreateSchema`; обяз. `name`,`provider`; `ollamaMode` только `local|cloud|null` (не `off`).
- `POST /api/credentials``{provider,name,apiKey}`.
- `POST /api/gateways``{name,endpoint,credentialId,isDefault}`.
- `POST /api/openclaw/gateway` → RPC `{method:"gateway.connect",params:{url,token}|{profileId}}`.
- БД: `/opt/swarmclaw/data/swarmclaw.db` (sqlite, таблицы `*_configs/profiles/agents/credentials` как `id+data JSON`), `memory.db`, `logs.db`.
## Домен swarm.dttb.ru (2026-06-08)
- **NPM proxy host #32** (LXC 103, 10.0.0.195): `swarm.dttb.ru``10.0.0.135:3456`, WSS on, block_exploits.
- **DNS:** wildcard `*.dttb.ru` есть только во **внутреннем** DNS (роутер) — http в LAN/NetBird заработал сразу. Публично wildcard НЕТ (каждый поддомен = отдельная A-запись в SpaceWeb). Добавил `swarm A 176.62.183.186` через [[../snippets/spaceweb-dns-api]] (`add-a`, **один вызов** — зона сверена до/после, 23→24 записи, ничего не задето; бэкап `/tmp/dttb_zone_before.txt`).
- **HTTPS/LE — ГОТОВО:** DNS пропагировался за ~90 сек, LE cert выпущен (NPM cert **id 118**, до 2026-09-06), `ssl_forced` on, проверено `https://swarm.dttb.ru/api/healthz → 200`. Грабля NPM API: LE cert принимает только `meta:{}` (с полями → "additional properties"); email/agree NPM подставляет сам. Challenge падал, пока DNS не пропагировался — не из-за meta.
- **Итог доступа:** `https://swarm.dttb.ru` (публично, за NPM+auth) и `http://swarm.dttb.ru` (LAN/NetBird). Вход — cookie `sc_auth` / ACCESS_KEY.
## TODO / опционально
- Снести Mac-app `SwarmClaw.app` (или оставить как клиент).
- Маппинг openclaw starter-агентов на gateway (роли/теги) — через UI.
- Самообучение SwarmClaw (`conversation-to-skill`) — **полуручное** (draft→approve), не автономное; для настоящего автообучения остаётся openclaw Dreaming.
## Связано
- [[openclaw]] — основной бот (LXC 137), теперь под управлением SwarmClaw
- [[2026-05-06-openclaw-opus-4-7-via-max-cliproxy]]