26 KiB
Executable File
tags, created, updated, status, ip
| tags | created | updated | status | ip | ||||
|---|---|---|---|---|---|---|---|---|
|
2026-05-11 | 2026-05-12 | hermes-pending | 192.168.1.14 |
OpenMediaVault на Raspberry Pi 5
Статус: Контейнеры запущены, Time Machine pending (май 2026) Цель: NAS на RPi 5 — OS на SD-карте, хранилище на USB 3.0 HDD
Прогресс
| Шаг | Статус | Заметки |
|---|---|---|
| 1 — Флашим SD | ✅ | Bookworm 2025-05-13, RPi Imager |
| 2 — Первый запуск + обновление | ✅ | apt upgrade выполнен |
| 3 — Установка OMV | ✅ | OMV 7 установлен |
| 4 — Первый вход в веб-интерфейс | ✅ | Пароль сменён |
| 5 — Сеть | ✅ | DHCP static lease 192.168.1.14 (eth0 MAC 2c:cf:67:64:03:f3); WiFi включён (wlan0, ASUS5, 192.168.1.15, 2026-05-19) |
| 6 — USB HDD | ✅ | 12TB Seagate ST12000NT001, EXT4, UUID 49e8f586-3839-4c5d-a1e1-58bfc3579ade, смонтирован через OMV в /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade |
| 7 — omv-extras + Docker | ✅ | omv-extras 7.0.6, Docker 29.4.3, kraken в группе docker |
| 8 — Контейнеры | ✅ | Все через отдельные docker compose, конфиги на HDD (см. ниже) |
| 9 — Time Machine share | ✅ | mbentley/timemachine:smb, расписание 10:00-22:00 GMT+6, HDD/timemachine |
| 10 — Перенос данных | N/A | не входит в этот гайд |
| 11 — Hermes агент Кракен | ✅ | Запущен, Telegram @kraken_htpc_bot живой, mcpvault ✅, obsidian RW, SOUL.md, browser/Playwright ✅, Spotify ✅ |
| 11а — Docker на HDD | ✅ | data-root + containerd перенесены на HDD через symlink, SD освободилась до 22% |
| 12 — Obsidian sync (Taiga↔Kraken↔Eagle) | ✅ | Все 3 узла работают, кроны активны, двусторонний sync протестирован |
| 13 — Vault wiki (llm-wiki) | ✅ | |
| 14 — SMB media share | ✅ | Samba вручную, шара media read-only guest. smbd enabled. |
Железо
- Raspberry Pi 5 (4 или 8 GB RAM)
- SD-карта ≥16 GB (Samsung/SanDisk A1 Class 10+)
- USB 3.0 HDD для хранения данных
- Проводной Ethernet (обязателен)
Шаг 1 — Флашим SD-карту
Образ: Raspberry Pi OS Lite 64-bit (Bookworm / Debian 12)
⚠️ Брать именно Bookworm, не Trixie (Debian 13) — OMV не поддерживается на Trixie!
- Последний Bookworm: 2025-05-13
- Прямая ссылка: https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2025-05-13/2025-05-13-raspios-bookworm-arm64-lite.img.xz
Инструмент: Raspberry Pi Imager (https://www.raspberrypi.com/software/)
⚠️ Не Balena Etcher — только RPi Imager поддерживает OS Customisation! При выборе образа из каталога (не custom file) появляется кнопка "Edit Settings"
Настройки (Edit Settings → шестерёнка):
- Hostname:
kraken - Username:
kraken(неadmin— зарезервировано для OMV!) - Password: сохранён в 1Password (запись "Kraken RPi")
- SSH: Enable → Allow public-key authentication → вставить
~/.ssh/id_rsa.pub
После флаша вставить карту в Pi и включить.
Шаг 2 — Первый запуск, обновление и настройка сети
SSH подключение (пока через WiFi/роутер):
ssh -i ~/.ssh/id_rsa kraken@kraken
Обновление системы:
sudo apt-get update && sudo apt-get upgrade -y
Static IP на eth0 (прямой кабель Mac ↔ Pi для установки):
sudo nmcli con add type ethernet ifname eth0 con-name eth0-static \
ipv4.method manual \
ipv4.addresses 192.168.100.2/24 \
ipv4.gateway 192.168.100.1 \
ipv4.never-default yes \
connection.autoconnect yes
sudo nmcli con up eth0-static
⚠️
ipv4.never-default yes— обязательно! Иначе интернет пойдёт через Mac, а не WiFi, и установка зависнет.
Шаг 3 — Установка OMV
# Pre-install
wget -qO- https://github.com/OpenMediaVault-Plugin-Developers/installScript/raw/master/preinstall | sudo bash
sudo reboot
# После перезагрузки — основная установка (~30 мин)
wget -qO- https://github.com/OpenMediaVault-Plugin-Developers/installScript/raw/master/install | sudo bash
Pi перезагрузится автоматически по окончании.
Шаг 4 — Первый вход в веб-интерфейс
- URL:
http://192.168.100.2(илиhttp://krakenчерез LAN) - Логин:
admin - Пароль:
openmediavault - Сразу сменить пароль! (System → General Settings → Web Administrator Password)
Шаг 5 — Сеть: DHCP + static lease, отключить WiFi
Переключить кабель Pi → роутер. Настроить DHCP через netplan (OMV управляет /etc/netplan/20-openmediavault-eth0.yaml):
network:
ethernets:
eth0:
match:
macaddress: "2c:cf:67:64:03:f3"
dhcp4: yes
dhcp6: no
link-local: []
В роутере (ASUS): добавить static lease в dhcp_staticlist через nvram:
ssh -i ~/.ssh/id_rsa admin@192.168.1.1 \
"nvram set dhcp_staticlist='...<2C:CF:67:64:03:F3>192.168.1.14>kraken>' && nvram commit && service restart_dnsmasq"
Отключить WiFi навсегда (modprobe blacklist):
sudo sh -c 'echo blacklist brcmfmac > /etc/modprobe.d/disable-wifi.conf' < /dev/null
sudo sh -c 'echo blacklist brcmutil >> /etc/modprobe.d/disable-wifi.conf' < /dev/null
sudo update-initramfs -u -k all < /dev/null
⚠️ Все sudo команды через SSH требуют
< /dev/null— иначе sudo ждёт stdin и зависает
Шаг 6 — USB HDD
- Подключить HDD к синему (USB 3.0) порту Pi
- Проверить скорость:
sudo apt install hdparm && sudo hdparm -t --direct /dev/sda→ должно быть ~200-250 MB/s - Разметить:
sudo parted -s /dev/sda mklabel gpt mkpart primary 0% 100% - Форматировать (агент не может — только вручную или через скрипт):
sudo bash /tmp/fmt.sh # скрипт с mkfs.ext4 -L storage /dev/sda1 - OMV Web UI → Storage → File Systems → выбрать
/dev/sda1→ Mount - OMV монтирует в:
/srv/dev-disk-by-uuid-<UUID>/
⚠️ Не монтировать вручную через fstab — OMV должен управлять монтированием сам
Шаг 7 — omv-extras + Docker
# omv-extras
wget -qO- https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | sudo bash < /dev/null
# Docker
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh && sudo sh /tmp/get-docker.sh < /dev/null
sudo usermod -aG docker kraken < /dev/null
Шаг 8 — Docker контейнеры
Каждый сервис — отдельный docker-compose.yml в /home/kraken/<name>/.
Все конфиги на HDD: /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/<name>/
| Сервис | Compose | URL | Данные |
|---|---|---|---|
| Portainer | /home/kraken/portainer/ |
:9000 | HDD/docker/portainer |
| Watchtower | /home/kraken/watchtower/ |
— | stateless |
| Home Assistant | /home/kraken/homeassistant/ |
:8123 | HDD/docker/homeassistant |
| Jellyfin | /home/kraken/media/ |
:8096 | HDD/docker/jellyfin, media:ro |
| Transmission | /home/kraken/media/ |
:9091 | HDD/docker/transmission, HDD/media/downloads |
| Prowlarr | /home/kraken/radarr/ |
:9696 | HDD/docker/prowlarr |
| Radarr | /home/kraken/radarr/ |
:7878 | HDD/docker/radarr, media:rw |
| Sonarr | /home/kraken/radarr/ |
:8989 | HDD/docker/sonarr, media:rw |
| Rclone | /home/kraken/rclone/ |
— | cron воскр. 03:00 → mailru-crypt:kraken/docker |
Управление:
cd /home/kraken/<name> && sudo docker compose up -d # запустить
cd /home/kraken/<name> && sudo docker compose restart # рестарт
cd /home/kraken/<name> && sudo docker compose pull && sudo docker compose up -d # обновить
⚠️ Watchtower: нужна переменная
DOCKER_API_VERSION=1.54— иначе крашится (API mismatch) ⚠️ sudo через SSH требует< /dev/nullдля каждой команды с tee/pipe
Media pipeline — Transmission hook + PGS→SRT
Статус: ✅ (2026-05-18)
Схема
Transmission → on-download-complete.sh → media-pipeline:kraken sync (NFO, библиотека)
→ pgs-to-srt.sh (PGS субтитры → SRT)
Файлы
HDD/docker/media-pipeline/
on-download-complete.sh — монтирован в Transmission как /config/on-download-complete.sh (ro)
pgs-to-srt.sh — конвертация PGS→SRT через pgsrip
config.json — конфиг media-pipeline
download-complete.log — лог загрузок
pgs-to-srt.log — лог конвертации
on-download-complete.sh
Запускается Transmission синхронно при завершении загрузки (script-torrent-done-filename).
Получает TR_TORRENT_DIR и TR_TORRENT_NAME — пути внутри контейнера (/downloads/...).
Вызывает pgs-to-srt.sh с путём /downloads/complete/radarr/... — скрипт сам переводит в хостовый путь.
⚠️ Скрипт выполняется внутри контейнера Transmission — хостовые пути недоступны напрямую.
/downloads→HDD/media/downloads,/media→HDD/mediaсмонтированы в контейнере. Не вызывать бинарники с хостовых путей ($HDD/...) — они недоступны внутри контейнера.
pgs-to-srt.sh
- Живёт на хосте (
HDD/docker/media-pipeline/), вызывается изon-download-complete.sh - Использует
mkvmerge -iдля детекции PGS/VobSub (быстрееmkvinfo) - PGS →
~/.local/bin/pgsrip -l ru -l en - VobSub →
SKIP(не реализовано) - Маркер
.sub-checkedрядом с mkv — пропускать уже проверенные файлы при bulk-скане - Флаг
-l ru -l en(два отдельных флага, не через запятую!)
Библиотека субтитров (итог скана 2026-05-18)
| Папка | Тип | Статус |
|---|---|---|
| documentaries-series/пингвины. шпион в толпе (3 файла) | HDMV PGS | ✅ .ru.srt + .en.srt |
| documentaries-series/жизнь птиц 1998 (10 файлов) | VobSub | ❌ не конвертированы (SKIP) |
| Всё остальное | SRT внутри mkv | ✅ транскода нет |
Remote path mapping (Radarr/Sonarr)
Transmission пишет в /downloads/complete/{radarr,sonarr}/... (внутри контейнера).
Radarr/Sonarr видят файлы через /media/downloads/....
Маппинг добавлен: host=transmission, remotePath=/downloads/, localPath=/media/downloads/.
Шаг 9 — Time Machine share
Контейнер: mbentley/timemachine:smb
Compose: /home/kraken/timemachine/docker-compose.yml
Данные: /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/timemachine/
Режим работы: restart: unless-stopped — контейнер стартует автоматически при загрузке и работает постоянно.
Credentials:
- Пользователь:
timemachine - Пароль:
timemachine⚠️ сменить позже
Подключение с Mac:
- Finder →
⌘K→smb://kraken - Логин:
timemachine/timemachine - System Preferences → Time Machine → Add Disk → выбрать
kraken
⚠️ Не останавливать контейнер резко (
docker stop) пока TM пишет бэкап — Samba оставляет stale lock наmbp-black.sparsebundle/lock. При следующем запуске TM не может смонтировать образ. Фикс: рестарт контейнера (docker restart timemachine).
Changelog — Time Machine
- 2026-05-14 — добавлен cron-контроль: запуск 04:00 UTC / остановка 16:00 UTC
- 2026-05-22 — cron убран,
restart: unless-stopped. Причина: резкая остановка через cron оставляла stale Samba lock → TM не мог смонтировать образ при следующем запуске
Шаг 14 — SMB media share
Статус: ✅ (2026-05-16)
Samba установлена как часть OMV, но плагин openmediavault-samba не используется — конфиг управляется вручную.
/etc/samba/smb.conf (шара добавлена в конец файла):
[media]
path = /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/media
comment = Kraken Media
browseable = yes
read only = yes
guest ok = yes
force user = kraken
smbd включён в автозапуск: sudo systemctl enable smbd
Подключение с Mac: Finder → ⌘K → smb://kraken → шара media → гостевой доступ.
⚠️ OMV не управляет smb.conf (плагин не установлен) — правки не слетают при
omv-salt deploy run. ⚠️ nmbd не нужен (disable netbios = yesв глобальных настройках OMV).
Шаг 10 — Перенос данных
Фильмы с Mac на NAS
rsync -avh --progress /path/to/movies/ kraken@kraken:/srv/.../media/movies/
Time Machine
⚠️ Старый TM-бэкап перенести нельзя напрямую — TM привязывает бэкап к конкретному диску/хосту. Начать новый бэкап на NAS, старый HDD хранить как архив или отформатировать после нескольких успешных новых бэкапов.
Hermes агент — ограничения и архитектура
Важно знать при отладке поведения агента.
Агент работает внутри контейнера hermes-kraken. Это означает:
| Возможность | Статус | Способ |
|---|---|---|
| Читать/писать vault | ✅ | /vault/ через mcpvault MCP |
| Писать файлы на хост | ✅ только через alpine+bind /:/host |
Portainer API |
| docker / docker cp | ❌ нет в контейнере | только Portainer API |
| SSH на хост | ❌ нет ключей | — |
| apt install | ⚠️ слетает при rebuild | не использовать |
| Portainer endpoint ID | 3 (не 1!) | проверять: GET /api/endpoints |
Передача файлов на хост — только base64
# Контент → base64 → Cmd alpine-контейнера → decode на хосте
B64=$(printf '%s' 'content' | base64 | tr -d '\n')
# Cmd: ["sh", "-c", "echo <B64> | base64 -d > /host/path && echo DONE"]
# HostConfig.Binds: ["/:/host"]
Никогда не использовать: echo с кавычками, printf escaping, heredoc — все они ломаются при передаче через Docker Cmd array.
Токены в Portainer API — не через shell-переменные
Hermes маскирует секреты как *** в terminal output. $TOKEN в JSON передаётся буквально.
Правильно: интерполировать значение ДО построения JSON (через Python), не в shell-строке curl.
Правило трёх попыток
Если действие не удаётся 3 раза — агент должен остановиться и сообщить пользователю.
Шаг 11 — Hermes агент Кракен
Статус: ✅ запущен (2026-05-12), mcpvault ✅ (2026-05-13)
Файлы
/home/kraken/hermes/
Dockerfile — образ hermes-kraken:latest
docker-compose.yml — restart: unless-stopped, network_mode: host
.env — API ключи
Конфиги и данные на HDD:
/srv/dev-disk-by-uuid-49e8f586.../docker/hermes/config/
config.yaml — основной конфиг Hermes
.local/bin/mcpvault — symlink → ../lib/node_modules/@bitbonsai/mcpvault/dist/server.js
.local/lib/node_modules/@bitbonsai/mcpvault/ — persistent, не слетает при rebuild
Toolsets (актуально 2026-05-13)
| Toolset | Статус |
|---|---|
| hermes-cli | ✅ |
| terminal | ✅ |
| file | ✅ |
| web (web_search + web_extract) | ✅ Tavily |
| browser (Playwright/Chromium) | ✅ (добавлен 2026-05-13) |
| memory | ✅ |
| spotify | ✅ токен скопирован с Eagle (PKCE, client_secret не нужен) |
| cronjob | ✅ |
⚠️ При сборке Кракена:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOADубран,npx playwright install --with-deps chromium --only-shellдобавлен в Dockerfile
⚠️ Spotify — plugin toolset. Нужно: 1)
spotifyвtoolsets:в config.yaml, 2)known_plugin_toolsets.telegram: [spotify]в config.yaml, 3)auth.jsonскопирован с Eagle (содержит refresh_token, PKCE).client_secretне нужен.
⚠️ SOUL.md не должен содержать
curl ... $TOKEN/KEY/SECRET— Hermes блокирует файл по паттернуexfil_curl. Заменять на псевдокод (# GET /api/...).
Модели (актуально 2026-05-13)
| Модель | Статус |
|---|---|
gemini-2.5-flash |
✅ primary |
| openrouter fallbacks | ✅ |
⚠️ Gemini prepaid кредиты исчерпаны (2026-05-14) — HTTP 429 RESOURCE_EXHAUSTED. Пока не пополнено, Кракен работает на OpenRouter free fallback (не поддерживает vision — изображения из Telegram не обрабатываются). Пополнить: https://aistudio.google.com/projects
Telegram бот
- Имя: Кракен / Bot: @kraken_htpc_bot
MCP серверы
| Server | Команда | Vault |
|---|---|---|
| obsidian | /opt/data/.local/bin/mcpvault /vault |
/home/kraken/obsidian → /vault:rw |
⚠️ mcpvault установлен через
npm install -g --prefix /opt/data/.local— живёт на HDD, переживает rebuild образа
⚠️ Vault монтируется как/vault:rw(не:ro!) — иначе mcpvault не может писать заметки
⚠️ config.yaml: указывать полный путь/opt/data/.local/bin/mcpvault— PATH в контейнере его не включает
⚠️ args:/vault(путь внутри контейнера), не/home/kraken/obsidian
Деплой / пересборка
# Сборка (осторожно — npm install съедает место на SD!)
cd /home/kraken/hermes && docker build -t hermes-kraken:latest .
# Если ENOSPC при сборке — сначала почистить build cache:
docker builder prune -af
# Запуск (docker compose не работает через SSH из-за long-lived process detection)
docker stop hermes-kraken && docker rm hermes-kraken
docker run -d --name hermes-kraken --restart unless-stopped --network host \
-v /srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker/hermes/config:/opt/data \
-v /home/kraken/obsidian:/vault:rw \
-e HERMES_UID=1000 -e HERMES_GID=1000 -e HERMES_ALLOW_ROOT_GATEWAY=1 \
--env-file /home/kraken/hermes/.env hermes-kraken:latest
# Проверка
docker logs hermes-kraken --tail 20
docker inspect hermes-kraken --format 'Status={{.State.Status}} Restarts={{.RestartCount}}'
TODO
- Настроить HA → создать Long-Lived token → вписать в HASS_TOKEN в .env
Перенести Spotify auth✅ скопирован с Eagle- Проверить SD backup cron (ручной запуск ✅ 6.3G/12мин; автозапуск — первое воскресенье 03:00)
Запуск контейнера:
docker run ... hermes-kraken:latest gateway run—gateway runуже в команде, compose не используется.
Шаг 11а — Docker и containerd на HDD
Статус: ✅ (2026-05-13)
SD карта 14GB быстро заполняется Docker образами. Всё перенесено на HDD.
Docker data-root
# /etc/docker/daemon.json
{"data-root": "/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker-data"}
containerd → symlink на HDD
sudo systemctl stop docker docker.socket containerd
sudo rsync -a /var/lib/containerd/ /srv/.../containerd/
sudo mv /var/lib/containerd /var/lib/containerd.bak
sudo ln -s /srv/.../containerd /var/lib/containerd
sudo systemctl start containerd docker
sudo rm -rf /var/lib/containerd.bak
Build cache (buildkit) — живёт на SD!
Buildkit cache НЕ управляется data-root — растёт на SD. Cron очистки:
# /etc/cron.d/docker-buildcache-cleanup
0 4 * * * root docker builder prune -af --filter until=24h > /dev/null 2>&1
При ручной сборке перед build: docker builder prune -af
Текущее состояние SD (после всех переносов)
- SD: ~22% используется (2.9GB из 14GB), 11GB свободно
- HDD: docker-data + containerd + build cache → не мусорят SD
Шаг 12 — Obsidian sync (Eagle ↔ Taiga ↔ Kraken)
Статус: ✅ работает на всех 3 узлах (протестировано 2026-05-13)
Подробная документация: obsidian-sync
Схема:
Eagle (полный vault ~/obsidian) ──push/pull──┐
Taiga (sparse: personal/ family/) ────────────├── TrueNAS bare repo
Kraken (sparse: personal/ family/) ───────────┘ mallexxx.duckdns.org:/mnt/RED_2TB/storage/git/obsidian-vault.git
Скрипты и кроны:
| Узел | Скрипт | Крон | Vault |
|---|---|---|---|
| Eagle | ~/scripts/sync-vault.sh |
0 * * * * |
~/obsidian (full) |
| Kraken | ~/scripts/sync-vault.sh |
0 * * * * |
~/obsidian (sparse) |
| Taiga | ~/sync-vault.sh (на хосте!) |
Hermes cron 0 * * * * |
/mnt/RED_2TB/docker/hermes/vault (sparse) |
⚠️ Тайга: скрипт запускается на хосте TrueNAS (не внутри контейнера) — только truenas_admin имеет ZFS ACL доступ к bare repo.
Шаг 13 — Vault wiki (llm-wiki / Karpathy approach)
Eagle-only: scheduled Hermes job раз в сутки запускает wiki-curation:
- Упорядочивает
wiki/папку по SCHEMA.md - Строит cross-references между страницами
- Резолвит git-конфликты вручную (semantic merge)
- Lint: orphans, broken links, stale content
TODO:
Создать✅ 2026-05-13wiki/SCHEMA.md,wiki/index.md,wiki/log.mdДобавить cron job на Eagle: ежедневно 02:00, skill✅ 2026-05-13llm-wikiНастроить✅ 2026-05-13WIKI_PATH=~/obsidian/wikiв Eagle.env
Уроки (что пошло не так при установке)
- Balena Etcher не поддерживает OS Customisation — использовать только RPi Imager
userconf.txtdeprecated на Bookworm — правильный способ через RPi Imager (он пишетcustom.toml)systemd.run=в cmdline.txt нужно указывать/usr/lib/raspberrypi-sys-mods/firstboot, а не свой скриптipv4.never-default yesпри настройке static IP на eth0 — обязательно, иначе интернет идёт через Mac и установка зависает- OMV install script при зависании — скорее всего нет интернета, проверить маршруты (
ip route)
Полезные ссылки
- Официальный вики OMV: https://wiki.omv-extras.org/
- Install script: https://github.com/OpenMediaVault-Plugin-Developers/installScript
- RPi Imager: https://www.raspberrypi.com/software/
- RPi Downloads: https://www.raspberrypi.com/software/operating-systems/