---
date: 2026-06-15
type: decision
tags: [decision, dttb, unifi, proxmox, lxc, network]
---

# UniFi Network Application на home lab — LXC 140 (2026-06-15)

## Задача
Развернуть контроллер UniFi (Network Application) на Proxmox home lab (10.0.0.250) + домен `unifi.dttb.ru`.

## Итог
- **LXC 140 `unifi`** — Debian 12, unprivileged + nesting/keyctl, Docker compose
- IP **10.0.0.196** (статика), nameserver **1.1.1.1**
- Ресурсы: 2 vCPU / 3 GB RAM / 16 GB диск (**rootfs на `work`** — `local-lvm` забит на 90%)
- Стек: `docker.io/mongo:4.4` + `docker.io/linuxserver/unifi-network-application:latest`, persistent bind-mount `/opt/unifi/{config,db}`
- Web UI: **https://10.0.0.196:8443** (302 на логин — поднялся), inform на :8080
- Домен: **unifi.dttb.ru** (NPM proxy host #36 → HTTPS 10.0.0.196:8443, WSS) + Let's Encrypt

## КОРЕНЬ (важная грабля): MongoDB 4.4, не выше
Хост HP Z800 = 2× **Xeon X5672 (Westmere)** — **без AVX** (`grep avx /proc/cpuinfo` пусто).
MongoDB **5.0+** (и 7.0, который ставит стандартный community-script `ct/unifi.sh`) требует AVX и падает с **`Illegal instruction`**.
LXC видит CPU хоста напрямую — маскировки нет. → берём **mongo:4.4** (последняя версия без AVX; UniFi 8.x поддерживает Mongo 3.6–7.0).
Проверка живости: `docker logs unifi-db` → `restarts=0`, «Waiting for connections», app подключился. Падений нет.

Native-установка на Debian 12 отпала: MongoDB 4.4 под bookworm в репах нет (4.4 собран под bullseye/libssl1.1). Docker-стек `mongo:4.4` самодостаточен и обходит это. Заодно это тот же стек, что отлажен на Передельках ([[2026-04-16-unifi-migration-peredelki]], там bind-mount решал сброс БД).

## Грабля 2: ghcr.io виснет из РФ
`lscr.io/linuxserver/...` редиректит на **ghcr.io** → закачка встала на 0 KB/s (compose висел). `mongo:4.4` с docker.io скачался нормально.
→ Образ переключён на **`docker.io/linuxserver/unifi-network-application:latest`** (linuxserver публикует и туда, и в ghcr). Скорость 1.2 MB/s. Если опять затык — NetBird Trance→finland exit или docker registry mirror.

## Домен и SSL (процедура как для omni — [[2026-05-26-omni-domain-and-update]])
DNS dttb.ru — на **Spaceweb** (нет публичного wildcard, каждый поддомен записью вручную).
1. `unifi.dttb.ru` → публично NXDOMAIN (DoH 1.1.1.1; с Mac `dig` хайджачится NetBird — [[feedback_dttb_dns_split_view]]).
2. Добавлена A-запись через Spaceweb API **одним** вызовом (НЕ в цикле — `editMain` циклом ломает зону):
   `POST https://api.sweb.ru/domains/dns` → `editMain action=add name=unifi type=A value=176.62.183.186` → `result:true`.
3. Negative-cache LE Boulder + 1.1.1.1 (TTL ~600) → ждать ~10 мин после первой неудачной попытки, потом выпуск.
4. NPM proxy host #36 создан (backend HTTPS 10.0.0.196:8443, WSS вкл). Cert Let's Encrypt **id 126** (exp 2026-09-13) выпущен и привязан (`ssl_forced`, http2).

Проверка: `https://unifi.dttb.ru` → **302 `/setup/`** (свежий контроллер), сертификат CN=unifi.dttb.ru issued by Let's Encrypt YE1.

## Доступы
- Proxmox: `ssh root@10.0.0.250` (1qaz!QAZ), `pct ... 140`
- Контейнер: `pct exec 140 -- ...`; compose в `/opt/unifi/`
- MongoDB (внутр.): user `unifi` / `Un1fiM0ngo2026`, db `unifi`/`unifi_stat`
- UniFi UI: https://10.0.0.196:8443 или https://unifi.dttb.ru — **первый вход = создание admin-аккаунта** (контроллер пустой)
- Spaceweb DNS: `it5870yand` / `1qaz!QAZ` (api.sweb.ru)
- NPM: 10.0.0.195:81, `it5870@yandex.ru` / `1qaz!QAZ`

## Управление
```bash
ssh root@10.0.0.250
pct exec 140 -- bash -c 'cd /opt/unifi && docker compose ps'
pct exec 140 -- bash -c 'cd /opt/unifi && docker compose restart'
pct exec 140 -- bash -c 'cd /opt/unifi && docker compose pull && docker compose up -d'  # апдейт
```

## Adoption устройств (2026-06-15, позже в тот же день)

Принимали **USW-Lite-16-PoE** (10.0.0.111) и **U7-LR**. Грабли:

### U7-LR не появлялся — физика порта свитча
Точка была в **порту 5** свитча: PoE подавался (Class 4, 4.41 Вт), но **линк down**, 0 пакетов, DHCP не получала; после передёргивания PoE детект вообще пропал (Class Unknown). → **битый порт/патч-корд**. Переткнули в **порт 8** — ожила: IP 10.0.0.243, линк 1000F, firmware 8.0.12. Вывод: «питание есть, а линка нет» = сначала кабель/порт, не контроллер.

### Stuck «Принятие» + ничего не автообнаруживается — Docker inform-host
Контроллер в Docker **bridge** отдавал устройствам inform-host = свой внутренний IP контейнера (`172.18.0.x`), до которого устройства не достучаться → adoption висит. Плюс заводская точка ищет `http://unifi:8080/inform`, а DNS-записи `unifi` не было.

**Фикс (рабочий, оставлен):**
1. **DNS на OpenWrt 10.0.0.1**: `uci add dhcp domain` → `name=unifi ip=10.0.0.196` → commit + `dnsmasq restart`. Теперь заводские устройства сами находят контроллер (как на Передельках).
2. **`system_ip=10.0.0.196`** в `/opt/unifi/config/data/system.properties` (был закомментирован `# system_ip=a.b.c.d`) + `docker restart unifi-network-application`. В логе стало `Current System IP: 10.0.0.196` (было `172.18.0.3`). Контроллер теперь отдаёт верный inform-host.
3. `set-inform http://10.0.0.196:8080/inform` на устройствах (ssh ubnt/ubnt) для немедленного появления.

Результат: оба `adopted:true` (проверено `docker exec unifi-db mongo unifi --eval 'db.device.find(...)'`).

### ⚠️ host networking НЕ применять (пробовал — откатил)
Переводил оба контейнера в `network_mode: host` — **сломалось**:
- linuxserver-образ кэширует mongo-URI в `system.properties` при первом старте и НЕ перечитывает env → в host остался `unifi-db:27017` (не резолвится) → `MongoTimeoutException`, краш-луп.
- контроллер в host автодетектил `Current System IP: 172.18.0.1` (docker-бридж), не 10.0.0.196.
Правильное решение — **оставить bridge + `system_ip` override**, а не host. Бэкап bridge-compose: `/opt/unifi/docker-compose.yml.bak-bridge-*`.

## Что осталось / на заметку
- **USG не adopt'ится — его физически нет в сети** (нет DHCP-аренды, нет на живых портах свитча, в БД контроллера 0 следов). Сначала запитать/воткнуть в живой порт; как появится — с DNS `unifi` + `system_ip` примется сам.
- `.196` — статика; убедиться, что вне DHCP-пула OpenWrt.
- При смене IP контроллера — обновить и DNS `unifi`, и `system_ip`.
