# TrueNAS — инфраструктура > Обновлено: 2026-09-01 (VPS qentra удалён — vless-proxy outbound мёртв; 443=Caddy, не Xray) > ## ⚠️ ПРИОРИТЕТ 2026-09-01: VPS qentra.top УДАЛЁН → vless-proxy и сетевые туннели сломаны > - **VPS `91.207.28.205` больше НЕ существует** (вся его Xray/OpenVPN/WG-инфраструктура утрачена). Подробно: [[family/how-to/vps-qentra]]. > - **Контейнер `vless-proxy`** (teddysun/xray): inbound SOCKS `0.0.0.0:1080` + HTTP `0.0.0.0:1081`, но **outbound ⇒ мёртвый `v.qentra.top:443`** (VLESS+WS+TLS, path `/qentra`, id `2D9F24C4-21FE-4784-9843-F11C384DA67A`). ⇒ Hermes-Taiga (ходит через `vless-proxy:1080`) **сейчас БЕЗ рабочего прокси**. > - **⚠️ На `mallexxx.duckdns.org:443` НЕ Xray**, а обычный **Caddy/nginx с валидным Let's Encrypt сертификатом** для `mallexxx.duckdns.org` (проверено `openssl s_client` 2026-09-01). Память «на 443 висел Xray server» — не подтвердилась. > - **Наружу открыты только 22 (SSH) и 443 (HTTPS/TLS)** с Kraken; `8443/8964/8080/9000` closed. > - **План замены** (выход клиентов сети TrueNAS через Kraken, Xray reverse — НЕ внедрён): [[personal/tech/xray-reverse-tunnel-kraken-truenas]]. > ## ✅ СТАТУС на 2026-08-25: пул ONLINE, docker поднят, почти все контейнеры Up > **Пул RED_2TB пересоздан (2026-08-21) и работает:** `zpool status` ONLINE, rsync возврата данных завершён, `/mnt/RED_2TB/` смонтирован. > **Docker: ПОДНЯТ на 2026-08-25.** Почти все контейнеры Up (zigbee2mqtt, webdav, vless-proxy, homeassistant, caddy, transmission, syncthing, mosquitto, nodered, immich*, gitea, filebrowser, portainer*, hermes-taiga и др.). ✅ **cups-splix поднят 2026-08-26** — образ собран заново (`docker build -t cups-splix .`), контейнер запущен `docker compose up -d`, порт 631 открыт, принтер `Samsung_CLX-216x_Series` активен (USB `04e8:3425`). Причина былого падения: образ локальный, потерян при восстановлении пула (`.ix-apps` не переносился), вручную не пересобирали. Рецепт — ниже, раздел «Печать / cups-splix». Ещё не подняты (проверить при надобности): inpxer/inpx-web/arr/ser2net. > **⚠️ Известная проблема modbus-bridge/mbusd — гонка с udev при рестарте TrueNAS:** > - После перезагрузки docker стартует раньше udev, поэтому `/dev/ttyZONT` и `/dev/ttyVent` на момент старта контейнеров ещё не существуют. > - Контейнеры с `devices: /dev/ttyZONT:...` падают на `start` с `error gathering device information while adding custom device "/dev/ttyZONT": no such file or directory` (ExitCode 128/255, RestartCount=0). > - `restart: unless-stopped` НЕ перезапускает такой контейнер (отказ до старта процесса). > - Следствие: modbus-bridge не отвечает на шине → 485-датчики в ZONT отображаются **«недоступные»**. > - Ручной фикс: `docker start modbus-bridge mbusd` (после готовности tty-симлинков). > - Защита от рецидива (план, НЕ внедрён — ждёт OK Alex): `family/plans/zont-modbus-bridge-udev-race-protection.md` — POSTINIT init script с ожиданием симлинков + `docker start`. > **⚠️ ДРУГОЕ (открытое):** пул `DEST` (IronWolf) на 2026-08-24 `DEGRADED` — разобраться, почему (отвалился mirror-член). TimeMachine (~277G) не возвращён (бэкапы macOS, вероятно не нужен — решение Alex не подтверждено). SSH с Mac по 192.168.2.197 нестабилен — использовать `mallexxx.duckdns.org`. > ## 🔒 ИСТОРИЯ: статус до восстановления (2026-08-24) > **Пул RED_2TB пересоздан и УЖЕ зареган в TrueNAS** — `zpool status` ONLINE (`mirror-0{sdc,sdf}`+`mirror-1{sde,sdd}`), `midclt call pool.query` id=1 RED_2TB ONLINE. rsync возврата данных ЗАВЕРШЁН (storage 3.29T, immich 353G, backup 287G, Edu 214G, Photos 146G, old-bu 65G, docker, docker.bak, system — все смонтированы). > **`.ix-apps` датасет (docker storage, был 24G) НЕ перенесён** — rsync шёл из `/mnt/RED_2TB/*` и не включал монтируемый в `/mnt/.ix-apps` системный датасет. Образы = кеш → перекачаются из registry сами; конфиги целы в `/mnt/RED_2TB/docker/`. > **Контейнеры запускались через `docker-compose`, НЕ через TrueNAS Apps (TrueCharts/Custom App).** daemon.json `data-root:/mnt/.ix-apps/docker`. `.ix-apps` = просто data-root docker, не TrueNAS Apps. > **⚠️ ДРУГОЕ (проверено 2026-08-24):** пул `DEST` (IronWolf, источник спасения) на момент проверки `DEGRADED` в `zpool list` — стоит разобраться, почему (вероятно отвалился mirror-член). Также SSH с Mac к TrueNAS по 192.168.2.197 нестабилен (`Connection reset/reset by peer`, `kex_exchange_identification read`), возможен конфликт сессий при активном входе на консоль — использовать `mallexxx.duckdns.org` и ретраи. > ## ⚠️ СТАТУС на 2026-08-21: пул RED_2TB — данные СПАСЕНЫ, пул OFFLINE, пересоздаём > **Выгрузка успешно завершена** (подтверждено Alex): данные RED_2TB (4.56T) на IronWolf (пул `DEST`, `/mnt/IRONWOLF`). **Пул RED_2TB — статус OFFLINE** в БД TrueNAS, НЕ импортирован. Конфиги docker (caddy, transmission, HA, immich и т.д.), Obsidian vault и git-репо спасены на `/mnt/IRONWOLF` (`system/`, `docker.bak/`, `docker/`, `storage/obsidian`, `storage/git`). > **ПЛАН (следующий шаг):** пересоздать пул RED_2TB с новой топологией `mirror {sdc,sdf}` + `mirror {sde,sdd}` (включаем WD2TB#2 зеркалом к WD2TB#1). Команды `zpool labelclear` + `zpool create` — в `family/how-to/truenas-sata-ports-and-zfs-pools.md` (раздел «Пересоздание пула 2026-08-21»). Затем вернуть данные rsync с IronWolf и восстановить инфраструктуру. > **ПРОТОКОЛ ПОВРЕЖДЕНИЯ (история):** пул паниковал на rw-импорте (`adding existent segment to range tree`, повреждённая space map). Работал только `zpool import -o readonly=on`. In-place починки нет (mav/iXsystems) — только спасать данные и пересоздавать. Полный рецепт — в `family/how-to/truenas-sata-ports-and-zfs-pools.md`. ## Доступ - **Host (external):** `mallexxx.duckdns.org` (DuckDNS) — **единственный способ** SSH/API из 192.168.1.x - **SSH:** `truenas_admin@mallexxx.duckdns.org -i ~/.ssh/id_rsa` - **Web UI:** http://truenas.mallexxx.duckdns.org - **Portainer:** https://portainer.mallexxx.duckdns.org - **Host (local network):** `192.168.2.197` — ⚠️ ИСПОЛЬЗОВАТЬ `ssh truenas_admin@mallexxx.duckdns.org`. НЕ ИСПОЛЬЗОВАТЬ локальный IP для SSH доступа! - ⚠️ Eagle (Mac, 192.168.1.x) и Kraken (192.168.1.15) находятся в **другой подсети** - ⚠️ Кра́кен и TrueNAS — **разные сети** (192.168.1.x vs 192.168.2.x). Доступ с Кракена на TrueNAS по локальному IP **не работает** ## Пользователи и группы (ключевые) | uid | Имя | gid | Назначение | |-----|-----|-----|------------| | 950 | truenas_admin | 950 | SSH-пользователь, управление docker | | 911 | transdamon | 911 | Процесс Transmission внутри контейнера | | 921 | transmission | 921 | Старый пользователь (не используется контейнером) | | 3000 | nas_users | 3000 | Общая группа доступа к NAS | ## Структура папок ``` /mnt/RED_2TB/ ├── docker/ ← конфиги docker-контейнеров (бэкапятся → mailru-crypt:) │ ├── caddy/ │ ├── filebrowser/ │ ├── ha/ ← Home Assistant │ ├── hermes/ ← Hermes-Taiga │ ├── homeassistant/ │ ├── immich/ │ ├── inpx-web/ │ ├── inpxer/ │ ├── mbusd/ │ ├── modbus-bridge/ │ ├── mosquitto/ │ ├── nodered/ │ ├── portainer/ │ ├── python/ │ ├── rclone/ │ ├── ser2net/ │ ├── transmission/ ← конфиг Transmission (settings.json, torrents, resume...) │ ├── vless-proxy/ │ ├── watchtower/ │ ├── webdav/ │ └── zigbee2mqtt/ ├── storage/ │ ├── Downloads/ ← данные торрентов (монтируется в контейнер как /mnt/storage) │ │ ├── transmission/ ← старый путь конфига (больше не используется) │ │ └── [медиафайлы] │ └── obsidian/ ← vault (read-only для hermes-taiga) ├── backup/ ← ручные бэкапы (бэкапятся → mailru-crypt:) │ └── transmission-config/ ← снапшот конфига от 2026-04-30 ├── Photos/ ← фото (бэкапятся → mailru:Photos/Photos) ├── old-bu/ ← старый архив (бэкапятся → mailru:Photos/old-bu) └── immich-photos-upload/ ← библиотека Immich (бэкапятся → mailru:Photos/immich) ``` ## NFSv4 ACL — важно TrueNAS использует **NFSv4 ACL**, а не стандартный POSIX chmod/chown. - `ls -la` показывает `----------` даже если ACL есть → всегда проверять через `midclt call filesystem.getacl ` - Добавить запись: `midclt call filesystem.setacl '{...}'` - `truenas_admin` не имеет passwordless sudo → root-операции только через midclt или TrueNAS UI ## Docker-контейнеры | Контейнер | Image | Порт | Домен | |-----------|-------|------|-------| | transmission | linuxserver/transmission:latest | 9091, 51413 | transmission.mallexxx.duckdns.org | | hermes-taiga | hermes-taiga:latest | — | — | | vless-proxy | teddysun/xray:latest | — | — | | filebrowser | filebrowser/filebrowser:latest | — | — | | webdav | hacdias/webdav:latest | — | webdav.mallexxx.duckdns.org | | homeassistant | home-assistant:stable | 8123 | mallexxx.duckdns.org | | immich-server | immich-app/immich-server:release | 2283 | immich.mallexxx.duckdns.org | | immich-postgres | tensorchord/pgvecto-rs:pg14-v0.2.0 | — | — | | immich-redis | redis:7 | — | — | | nodered | nodered/node-red:latest | 1880 | nodered.mallexxx.duckdns.org | | mosquitto | eclipse-mosquitto:latest | — | — | | caddy | caddy:latest | 80, 443 | reverse proxy для всего | | rclone | rclone/rclone:latest | — | бэкап по cron | | portainer | portainer/portainer-ce:latest | 9000 | portainer.mallexxx.duckdns.org | | watchtower | containrrr/watchtower:latest | — | авто-обновление образов | | inpxer | ghcr.io/hedger/inpxer:latest | 18080 | books.mallexxx.duckdns.org | | nodered | node-red:latest | 1880 | nodered.mallexxx.duckdns.org | | zigbee2mqtt | koenkk/zigbee2mqtt:latest | — | — | | mbusd | 3cky/mbusd:latest | — | Modbus | | modbus-bridge | modbus-bridge | — | — | | cups-splix | cups-splix | — | принтер | ### cups-splix — принтер Samsung CLX-216x (✅ поднят 2026-08-26; ✅ mDNS-фикс 2026-08-31 завершён) **Статус:** контейнер работает, принтер `Samsung_CLX-216x_Series` **idle / enabled / accepting**. CUPS слушает `0.0.0.0:631` (host-сеть). mDNS-анонс **включён** — штатная Android print service теперь видит принтер по mDNS (подробно: [[mac-print-shared-services]]). См. ниже раздел «✅ mDNS/AirPrint анонс принтера». Папка: `/mnt/RED_2TB/docker/cups/` → `Dockerfile`, `entrypoint.sh`, `docker-compose.yml`, `data/`→`/etc/cups`, `cache/`→`/var/cache/cups`, `spool/`→`/var/spool/cups`, `uld/`, бэкап `backup_20260831-003619.tar.gz`. - **Image:** `cups-splix` (локальная сборка из Dockerfile; старый образ сохранён как `cups-splix-old` для отката) - **Dockerfile** (debian:12-slim): `cups-daemon cups-client cups-common printer-driver-splix avahi-daemon avahi-utils dbus usbutils nano procps`; `cupsadmin:admin` (группа lpadmin); `COPY entrypoint.sh`; `EXPOSE 631`; `ENTRYPOINT ["/entrypoint.sh"]` - **entrypoint.sh:** `dbus-daemon --system --fork` → `avahi-daemon --no-drop-root --syslog` (фон) → `exec cupsd -f` - **compose:** `image: cups-splix`, `network_mode: host`, `privileged: true`, volume `/dev/bus/usb:/dev/bus/usb`, restart `unless-stopped` (содержит устаревший `command: [cupsd -f]`, но ENTRYPOINT переопределяет — правится только через root/UI, файл 600 root) - **Сборка/поднятие (⚠️ полное пересоздание, НЕ `docker restart`):** ```bash cd /mnt/RED_2TB/docker/cups/ docker build -t cups-splix-new . docker stop cups-splix && docker rm cups-splix docker tag cups-splix-new cups-splix && docker tag cups-splix cups-splix-old 2>/dev/null docker compose up -d ``` > Полный разбор и симптом «телефон не видит принтер»: [[mac-print-shared-services]] ### Инвентарь compose-файлов по папкам (проверено 2026-08-24) Каждый контейнер = своя папка `/mnt/RED_2TB/docker//`. Модель — **не один общий compose, а per-service compose** (контейнеры поднимались `docker compose up -d` из своей папки / `docker run`). **✅ Есть `docker-compose.yml` (поднимаются `docker compose -f ... up -d`)** — 21 шт: arr, caddy, cups, filebrowser, gitea, hermes, immich, inpx-web, inpxer, library, mbusd, mosquitto, nodered, portainer-mcp, portainer, rclone, ser2net, syncthing, transmission, vless-proxy, watchtower **⚠️ НЕТ compose-файла — только конфиг (восстанавливать вручную, параметры из доки ниже):** - **ha** — Home Assistant: `/mnt/RED_2TB/docker/ha/` (automations.yaml). Образ `ghcr.io/home-assistant/home-assistant:stable`, порт `8123`, volume `/mnt/RED_2TB/docker/ha` → `/config`. - **webdav** — `/mnt/RED_2TB/docker/webdav/` (config.yml). Образ `hacdias/webdav:latest`, домен webdav.mallexxx.duckdns.org. - **modbus-bridge** — `/mnt/RED_2TB/docker/modbus-bridge/` (config.yml + modbus_ha_bridge.py). Образ `modbus-bridge` (локальная сборка из репо `HA-ZONT-Modbus`). Volumes: config.yml → `/app/config.yml` (ro), modbus_ha_bridge.py → `/app/modbus_ha_bridge.py` (ro). - **zigbee2mqtt** — `/mnt/RED_2TB/docker/zigbee2mqtt/` (configuration.yaml). Образ `koenkk/zigbee2mqtt:latest`, работает через mosquitto. - **homeassistant** — в доке упомянут как отдельный контейнер (порт 8123, volume → /config); папка `docker/homeassistant/` есть, но название контейнера в таблице `homeassistant`, а папка конфига HA фактически `ha/`. При восстановлении сверить, какой реально используется. ### Порядок восстановления docker-стека (зависимости) 1. **docker engine:** `systemctl enable --now docker` (после создания data-root, см. шапку). Проверка: `docker info | grep -iE "Server Version|Docker Root Dir"`. 2. **Инфраструктура/сеть:** mosquitto (MQTT) → zigbee2mqtt (нужен mosquitto) → nodered (MQTT) → caddy (прокси, тянет все домены) → vless-proxy (SOCKS5 для hermes). 3. **Умный дом:** mbusd (Modbus TCP:502) → modbus-bridge (через mbusd) → ha (homeassistant, нужен caddy для домена). 4. **Медиа/хранилище:** transmission (нужен caddy) → arr (radarr/sonarr/prowlarr) → inpxer (books), inpx-web, library → rclone, syncthing, filebrowser, webdav, gitea. 5. **Сервисы/свои:** hermes-taiga (нужен vless-proxy), portainer, portainer-mcp, watchtower, cups, ser2net. 6. **Проверка:** `docker ps`. HA: `docker exec homeassistant python -m homeassistant --script check_config --config /config`. ### Transmission — детали - **Config:** `/mnt/RED_2TB/docker/transmission/` (монтируется как `/config`) - **Данные:** `/mnt/RED_2TB/storage` (монтируется как `/mnt/storage`) - **Download dir:** `/mnt/storage/Downloads` - **UID/GID:** 911/911 (пользователь `transdamon`) - **RPC whitelist:** `172.16.6.*` - **Web:** https://transmission.mallexxx.duckdns.org - **Порты:** 9091 (RPC/web), 51413 (TCP/UDP peers) ### Caddy — домены | Домен | → | |-------|---| | mallexxx.duckdns.org | Home Assistant :8123 | | transmission.mallexxx.duckdns.org | Transmission :9091 | | immich.mallexxx.duckdns.org | Immich :2283 | | nodered.mallexxx.duckdns.org | Node-RED :1880 | | webdav.mallexxx.duckdns.org | WebDAV | | books.mallexxx.duckdns.org | Inpxer :18080 🔒 basicauth (user: books-admin) | | library.mallexxx.duckdns.org | library-app :8080 🔒 basicauth (user: books-admin) | | portainer.mallexxx.duckdns.org | Portainer :9000 | | truenas.mallexxx.duckdns.org | TrueNAS UI :80 | | cam.mallexxx.duckdns.org | Камера :8090 | | docs.mallexxx.duckdns.org | Docs :8000 | ### Home Assistant — детали - **Image:** `ghcr.io/home-assistant/home-assistant:stable` - **Порт:** `8123:8123` - **Volume:** `/mnt/RED_2TB/docker/ha` → `/config` - Конфиги редактируются **напрямую на NAS** — `docker cp` не нужен, изменения применяются после reload/restart HA. **Ключевые файлы конфига:** | Файл | Назначение | |------|------------| | `configuration.yaml` | Главный конфиг: интеграции, template sensors, http trusted_proxies | | `automations.yaml` | Все автоматизации (подключён через `!include`) | | `scripts.yaml` | Скрипты | | `.storage/lovelace.home_plan` | Dashboard с планом этажей (JSON, управляется HA UI) | | `www/floorplan/floor1_ha.svg` | SVG фон первого этажа | | `www/floorplan/floor2_ha.svg` | SVG фон второго этажа | **Перезапуск после редактирования конфига:** ```bash ssh truenas_admin@mallexxx.duckdns.org "docker restart homeassistant" ``` **Проверка конфига перед перезапуском:** ```bash ssh truenas_admin@mallexxx.duckdns.org "docker exec homeassistant python -m homeassistant --script check_config --config /config" ``` ### mbusd — Modbus RTU → TCP gateway Мост Modbus RTU → TCP: пробрасывает серийный порт в TCP 502. Используется и для вентиляции (AT2), и для ZONT-шины. - **Image:** `3cky/mbusd`, compose в `/mnt/RED_2TB/docker/mbusd/` - **Порт:** `502:502` (TCP) - **Config:** `/mnt/RED_2TB/docker/mbusd/mbusd.conf` → `/etc/mbusd.conf` (`device=/dev/ttyUSB0 speed=9600 mode=8n1`, `port=502`) - **Device:** `devices: - /dev/ttyVent:/dev/ttyUSB0` - **Entrypoint:** `["/usr/bin/mbusd","-d","-L","-","-c","/etc/mbusd.conf"]` - **Pitfall udev-race:** см. ниже «Проблема modbus-bridge/mbusd после рестарта». ### modbus-bridge — 485-датчики + виртуальные slaves для ZONT Кастомный Python-мост (`modbus_ha_bridge.py`, репо `HA-ZONT-Modbus`), контейнер `/mnt/RED_2TB/docker/modbus-bridge/`. - **Image:** `modbus-bridge` (локальная сборка, `--no-cache`). **НЕ имеет compose-файла** — создавался через `docker-compose`-подобный run; для восстановления использовать параметры ниже. - **Device:** `devices: - /dev/ttyZONT:/dev/ttyUSB0` (внутри контейнера слушает `/dev/ttyUSB0`) - **Volumes:** `config.yml` → `/app/config.yml` (ro), `modbus_ha_bridge.py` → `/app/modbus_ha_bridge.py` (ro) - **Env (из compose):** `HA_TOKEN`, `MQTT_USER=zont`, `MQTT_PASS=...` - **`network_mode: host`**; MQTT broker `localhost:1883` (mosquitto), HA `http://localhost:8123`. **Роль (важно — два режима работы):** 1. **Sniff (чтение)** — сниффит реальные 485-датчики на шине ZONT: **Dining=slave 1, Kids=slave 2, Bedroom=slave 3** (CO₂/температура/влажность, регистры 2 и 100) и публикует в MQTT (`modbus/sensors//...`), а также пишет в HA. 2. **Mappings (виртуальные slaves для ZONT)** — подставляет на **slave 101/102/103** (регистр 100) значения temperature от 485-датчиков: Dining→101, Kids→102, Bedroom→103. **ZONT (Modbus master) опрашивает 101/102/103 как свои внешние датчики температуры.** Есть также wifi-термостат как slave 100 (`sensor.0xa4c13862d39377e6_temperature`) и Socket 1 = slave 101 через switch (обратим внимание: 101 занят и Dining temp — переиспользуется на одном slave с разными функциями; сверить в config.yml). 3. Также через mbusd может работать с AT2 вентиляции. **Если modbus-bridge не слушает `ttyZONT`** (упал/не запущен) → ZONT не получает ответ на запросы slave 101/102/103 → в интерфейсе ZONT 485-датчики отображаются **«недоступные»**. ### Проблема modbus-bridge/mbusd после рестарта TrueNAS (гонка с udev) **Симптом:** после перезагрузки TrueNAS `/dev/ttyZONT` и `/dev/ttyVent` присутствуют (`ttyZONT`→ttyUSB1, `ttyVent`→ttyUSB0, создаются init script id=1), НО контейнеры `modbus-bridge`/`mbusd` упали на старте и не перезапустились; 485-датчики в ZONT «недоступные». **Причина:** docker стартует раньше udev → при `start` контейнера устройство ещё не существует → падение ДО запуска процесса: ``` docker inspect --format '{{.State.Error}}' error gathering device information while adding custom device "/dev/ttyZONT": no such file or directory # ExitCode 128 / 255, RestartCount=0 ``` `restart: unless-stopped` такой отказ **не подхватывает** (RestartCount=0), и задержка внутри entrypoint не поможет (device mount происходит до старта процесса). **Ручной фикс:** `docker start modbus-bridge mbusd` (после того как симлинки созданы). **Защита от рецидива (план, НЕ внедрён, ждёт OK Alex):** `family/plans/zont-modbus-bridge-udev-race-protection.md` — POSTINIT init script `/mnt/RED_2TB/system/start-modbus.sh`, который ждёт появления `ttyZONT`/`ttyVent` (≤25с) и делает `docker start modbus-bridge mbusd`. ### USB device aliases Файл правил: `/mnt/RED_2TB/system/99-tty-alias.rules` ``` SUBSYSTEM=="tty", KERNEL=="ttyUSB*", KERNELS=="?-1.6:1.0", SYMLINK+="ttyZONT" SUBSYSTEM=="tty", KERNEL=="ttyUSB*", KERNELS=="?-1.5:1.0", SYMLINK+="ttyVent" ``` `?` — wildcard на префикс USB-шины (`2`, `3` и т.д.): правила работают даже если хаб переопределяется под другой контроллер (например, после подключения USB3-устройства к тому же хабу). Применить после изменений: ```bash cp /mnt/RED_2TB/system/99-tty-alias.rules /etc/udev/rules.d/ && udevadm control --reload-rules && udevadm trigger ``` > `/etc/udev/rules.d/` на TrueNAS — tmpfs, не переживает перезагрузку. Правила применяются автоматически через **TrueNAS Init/Shutdown Scripts** (POSTINIT). **Просмотреть/изменить:** TrueNAS UI → System → Advanced → Init/Shutdown Scripts, или: ```bash midclt call initshutdownscript.query ``` Текущая запись (id 1, POSTINIT, comment: "Map ttyUSB"): ```bash cp /mnt/RED_2TB/system/99-tty-alias.rules /etc/udev/rules.d/ && udevadm control --reload-rules && udevadm trigger ``` ## Hermes-Taiga агент | Параметр | Значение | |----------|----------| | Контейнер | `hermes-taiga` | | Telegram | через общий токен, SOCKS5 прокси `vless-proxy:1080` | | Модель | **DeepSeek Chat** (`deepseek/deepseek-chat`) | | Auxiliary | OpenRouter (`openrouter/auto`) | | Vault (хост) | `/mnt/RED_2TB/storage/obsidian` | | Vault (контейнер) | `/vault:rw` | | obsidian-mcp | `/opt/data/.local/bin/mcpvault /vault` | | Scope | sparse: `personal/ + family/` | | Toolsets | hermes-cli, file, web, browser | | web_search | Tavily (`TAVILY_API_KEY` в .env) | | web_extract | ✅ HTTP-парсинг | | browser | ✅ Playwright/Chromium (headless, JS-heavy сайты) | | Прокси | SOCKS5 `vless-proxy:1080` (HTTP/HTTPS/Telegram — все через прокси) | ### SOUL.md — identity & persona (обновлено 2026-05-13) Файл: `/opt/data/SOUL.md` (монтируется в контейнер, читается Hermes на каждый тёрн). **Ключевые изменения 2026-05-13:** - Добавлен блок `## Identity` — Тайга не ассистент, а лес: не извиняется, не суетится, говорит прямо - Добавлен uncertainty posture: при отсутствии данных говорит "не знаю" / "нет данных в vault", не строит истории - Тон исправлен: убрано "тёплая" (активировало female-helper архетип), оставлено "спокойная, уверенная, немногословная" - Добавлена обязанность читать и писать в Obsidian (RULE 2, Vault Access с правильными MCP-командами) - `display.personality` в config.yaml изменён с `helpful` на `neutral` — убирает Hermes-level "helpful" прайминг поверх soul **Почему важно:** `display: personality: helpful` в config.yaml инжектировался поверх soul.md и был основным источником извинений и гиперкомпенсации. ### Починка root-проблемы (2026-05-13) Hermes обновился — появилась проверка на root. Контейнер падал с `Refusing to run as root`. Фикс: `HERMES_ALLOW_ROOT_GATEWAY=1` + `UV_CACHE_DIR=/tmp/uv-cache` в docker-compose.yml + пересборка с `--no-cache`. > ⚠️ При обновлении образа — всегда `docker build --no-cache`, иначе `.venv` остаётся от root-слоя и ломает permissions. ## Obsidian Sync (Taiga) **Скрипт:** `~/sync-vault.sh` (запускается на **хосте**, не в контейнере) **Крон:** Hermes cron job `0 * * * *` **Bare repo:** `file:///mnt/RED_2TB/storage/git/obsidian-vault.git` **Лог:** `/tmp/vault-sync.log` ```bash # Запустить sync вручную: bash ~/sync-vault.sh # Посмотреть лог: tail -20 /tmp/vault-sync.log # История коммитов: git -C /mnt/RED_2TB/storage/git/obsidian-vault.git log --oneline -10 ``` > ⚠️ Скрипт запускается от `truenas_admin` — только этот пользователь имеет ZFS ACL доступ к bare repo и vault папке. Подробности: [[obsidian-sync]] ## Home Assistant — что настроено ### `configuration.yaml` - `http:` раздел: `use_x_forwarded_for: true`, `trusted_proxies: 172.16.0.0/12` — обязательно для работы через reverse proxy (Caddy) - Modbus интеграция для вентиляторов AT2 и заслонок - Template sensors (в блоке `template: - sensor:`): | Сенсор | Пример | Описание | |--------|--------|----------| | `dining_summary` | "24° 450ppm" | Темп и CO₂ в столовой | | `dining_air_summary` | "65tvoc 3pm" | TVOC и частицы в столовой | | `kids_summary` | "22° 600ppm" | Темп и CO₂ в детской | | `bedroom_summary` | "21° 500ppm" | Темп и CO₂ в спальне | | `at2_1_summary` | "Off" / "45%" | AT2-1: объединённые on/off + скорость | | `at2_2_summary` | "Off" / "45%" | AT2-2: объединённые on/off + скорость | ### `automations.yaml` - ГВС циркуляция: вкл (09:30) / выкл (23:00) - Вентиляционный вентилятор вкл в 05:00 - Проходной выключатель кабинета → toggle света в кабинете (`not_from: [unavailable, unknown]` — защита от ложных срабатываний при запуске HA) - Подсветка лестницы: вкл/выкл по датчику освещённости - Диммер спальни: toggle и цикл яркости - Ночной свет в душе: присутствие + освещённость - Уведомление: датчик протечки (котельная) - Уведомления: низкий заряд батареи (несколько устройств) ### Floor Plan Dashboard (`lovelace.home_plan`) Два вида — Ground Floor (`floor1`) и Second Floor (`floor2`) — `picture-elements` поверх SVG фона. **Первый этаж (`floor1`):** - Приточные заслонки: столовая (левая/правая), кабинет - Вытяжные заслонки: кухня, туалет 1F - Вентилятор 3 (кухонная вытяжка) - Метки AT2-1 / AT2-2 (`sensor.at2_1_summary` / `sensor.at2_2_summary`) - Сауна, обогревательный кабель - Свет кабинет (левый/правый) - Метка столовой (`sensor.dining_summary`) и качество воздуха (`sensor.dining_air_summary`) **Второй этаж (`floor2`):** - Приточные заслонки: детская, спальня, север - Вытяжные заслонки: ванная, душ 2F - Свет спальни (диммер) - Метки: `sensor.kids_summary`, `sensor.bedroom_summary` **SVG dark mode** — встроенный CSS в SVG-файлах: ```svg ``` > ЖJSON Lovelace зафиксирован в git по пути `floorplan/lovelace.home_plan.json` (справочный снимок, HA **не** подгружает его автоматически). --- ## Печать / cups-splix (2026-08-26, починено) **Принтер Samsung CLX-216x подключён по USB к TrueNAS** (не в сети!). Единственный путь печати — контейнер `cups-splix`, который раздаёт CUPS на `192.168.2.197:631`. **Почему телефон не видел принтер (2026-08-26):** после пересоздания пула контейнер `cups-splix` **не был поднят** — образ локальный (не registry), стёрлся вместе с `.ix-apps`; при восстановлении его не пересобирали (пометка «проверить при надобности»). Конфиг `/mnt/RED_2TB/docker/cups/data` (это `/etc/cups`) цел → принтер прописан и подцепился после рестарта сам. **Рецепт подъёма (при «не вижу принтер»):** ```bash cd /mnt/RED_2TB/docker/cups docker build -t cups-splix . # образ локальный, собрать заново (~3.5 мин) docker compose up -d # поднять (privileged + /dev/bus/usb) docker exec cups-splix lpstat -p -d # проверить принтер nc -z 192.168.2.197 631 # проверить порт наружу ``` - Принтер: `usb://Samsung/CLX-216x%20Series?serial=9566BAGQ213134Z.&interface=1` (USB ID `04e8:3425` Samsung CLX-216x). - Порт 631: открыт наружу после подъёма. ### ✅ mDNS/AirPrint анонс принтера — включён 2026-08-31 (Android print service видит принтер) Проблема: Android **штатная служба печати** (в отличие от Samsung Mobile Print, который ходит прямо по IP) ищет принтер **только через mDNS/Bonjour** (`_ipp._tcp.local`). CUPS не анонсировал: в контейнере не было `avahi-daemon`, а `printer-dns-sd-name` в IPP был `no-value` → Android помечал принтер «недоступен», даже добавленный вручную по IP. **Решение (выполнено):** пересобрали cups-splix — теперь запускает `dbus-daemon` + `avahi-daemon` рядом с cupsd через `entrypoint.sh`, и в `cupsd.conf` включено `Browsing On` + `BrowseLocalProtocols dnssd`. После этого CUPS регистрирует принтер в avahi → mDNS-анонс с **`mopria-certified=1.3`** на IPv4 `192.168.2.197` физического интерфейса `enp3s0`. Android (Mopria) теперь находит принтер сам в локальной сети. **Что изменилось в конфиге** (папка `/mnt/RED_2TB/docker/cups/`): - `Dockerfile`: добавлен `avahi-daemon` в apt, написан `entrypoint.sh`, `ENTRYPOINT` вместо `CMD` (`.old` образ сохранён как `cups-splix-old`). - `entrypoint.sh`: стартует `dbus-daemon --system`, затем `avahi-daemon --no-drop-root`, затем `exec cupsd -f`. - `data/cupsd.conf`: `Browsing Off` → `Browsing On` + добавлена строка `BrowseLocalProtocols dnssd` (бэкап `cupsd.conf.pre-avahi`). **⚠️ Важный питфолл:** после правки конфига НЕ использовать `docker restart cups-splix` — он убивает avahi-daemon (defunct), перед новым подъёмом обязателен **`docker stop cups-splix && docker rm cups-splix && docker compose up -d`** (полный пересоздание, чтобы entrypoint перевыполнился с нуля). **Проверка анонса:** ```bash docker exec cups-splix sh -c "timeout 6 avahi-browse -rt -p _ipp._tcp | grep ';enp3s0;IPv4;'" # должно показать: ... Samsung\032CLX-216x... truenas.local;192.168.2.197;631; "mopria-certified=1.3" ... ``` **Бэкап конфига (2026-08-31):** `/mnt/RED_2TB/docker/cups/backup_20260831-003619.tar.gz` (md5 `0e303a6a57ae767d1e14cd72c8039fe4`) — tar из /etc/cups, /var/spool/cups, /var/cache/cups. > Диагностика и полное объяснение: [[mac-print-shared-services]] > ⚠️ **2026-08-31: топология изменена.** TrueNAS больше НЕ в локальной сети (только публичный DNS `mallexxx.duckdns.org`) — из других подсетей/внешки `192.168.2.197` недостижим, и **снаружи `mallexxx.duckdns.org:631` закрыт**. НО **из самой подсети `192.168.2.x` TrueNAS достижима** (телефон `192.168.2.141` успешно печатал по `192.168.2.197:631` — CUPS access_log это подтверждает). → Samsung Mobile Print (app) печатает (висит на локальном IPP внутри подсети), а штатная Android print service с `ipp://192.168.2.197:631/...` показывала «недоступен» из-за **отсутствия mDNS/AirPrint-анонса** (avahi-daemon не запущен; `printer-dns-sd-name = no-value`). ✅ **Исправлено** (см. раздел «✅ mDNS/AirPrint анонс принтера»): cups-splix пересобран с avahi-daemon, cupsd.conf получил `Browsing On` + `BrowseLocalProtocols dnssd` → принтер анонсируется по mDNS (`mopria-certified=1.3`, IPv4 `192.168.2.197`); Android-служба теперь находит принтер сама. Детали и откат: [[mac-print-shared-services]]. ## Связанные заметки - [[truenas-access]] — SSH-доступ - [[truenas-rclone-backup]] — система бэкапов - [[obsidian-sync]] — Obsidian sync Eagle ↔ Taiga ↔ Kraken - [[openmediavault-rpi5]] — Kraken NAS (Hermes агент, sync)