--- tags: - raspberry-pi - nas - openmediavault - how-to created: '2026-05-11' updated: '2026-05-12' status: hermes-pending ip: 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 отключён (modprobe blacklist brcmfmac/brcmutil) | | 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 — Перенос данных | 🔲 | | | 11 — Hermes агент Кракен | ✅ | Запущен, Telegram @kraken_htpc_bot живой, mcpvault подключён, obsidian RW, SOUL.md настроен | | 11а — Docker на HDD | ✅ | data-root + containerd перенесены на HDD через symlink, SD освободилась до 22% | | 12 — Obsidian sync (Taiga↔Kraken↔Eagle) | ✅ | Все 3 узла работают, кроны активны, двусторонний sync протестирован | | 13 — Vault wiki (llm-wiki) | 🔲 | Eagle: scheduled wiki-curation job, Karpathy-style | --- ## Железо - 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/роутер): ```bash ssh -i ~/.ssh/id_rsa kraken@kraken.local ``` Обновление системы: ```bash sudo apt-get update && sudo apt-get upgrade -y ``` Static IP на eth0 (прямой кабель Mac ↔ Pi для установки): ```bash 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 ```bash # 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.local`) - Логин: `admin` - Пароль: `openmediavault` - **Сразу сменить пароль!** (System → General Settings → Web Administrator Password) --- ## Шаг 5 — Сеть: DHCP + static lease, отключить WiFi Переключить кабель Pi → роутер. Настроить DHCP через netplan (OMV управляет `/etc/netplan/20-openmediavault-eth0.yaml`): ```yaml network: ethernets: eth0: match: macaddress: "2c:cf:67:64:03:f3" dhcp4: yes dhcp6: no link-local: [] ``` В роутере (ASUS): добавить static lease в `dhcp_staticlist` через nvram: ```bash 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): ```bash 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 1. Подключить HDD к синему (USB 3.0) порту Pi 2. Проверить скорость: `sudo apt install hdparm && sudo hdparm -t --direct /dev/sda` → должно быть ~200-250 MB/s 3. Разметить: `sudo parted -s /dev/sda mklabel gpt mkpart primary 0% 100%` 4. Форматировать (агент не может — только вручную или через скрипт): ```bash sudo bash /tmp/fmt.sh # скрипт с mkfs.ext4 -L storage /dev/sda1 ``` 5. OMV Web UI → Storage → File Systems → выбрать `/dev/sda1` → Mount 6. OMV монтирует в: `/srv/dev-disk-by-uuid-/` > ⚠️ Не монтировать вручную через fstab — OMV должен управлять монтированием сам --- ## Шаг 7 — omv-extras + Docker ```bash # 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//`. Все конфиги на HDD: `/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker//` | Сервис | 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 | | Rclone | `/home/kraken/rclone/` | — | cron воскр. 03:00 → mailru-crypt:kraken/docker | Управление: ```bash cd /home/kraken/ && sudo docker compose up -d # запустить cd /home/kraken/ && sudo docker compose restart # рестарт cd /home/kraken/ && sudo docker compose pull && sudo docker compose up -d # обновить ``` > ⚠️ Watchtower: нужна переменная `DOCKER_API_VERSION=1.54` — иначе крашится (API mismatch) > ⚠️ sudo через SSH требует `< /dev/null` для каждой команды с tee/pipe --- ## Шаг 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/` **Расписание** (crontab kraken-пользователя): - `0 4 * * *` UTC (10:00 GMT+6) → `/usr/local/bin/tm-start.sh` — поднять контейнер - `0 16 * * *` UTC (22:00 GMT+6) → `/usr/local/bin/tm-stop.sh` — остановить контейнер - `restart: no` — при загрузке Pi не стартует автоматически **Credentials:** - Пользователь: `timemachine` - Пароль: `timemachine` ⚠️ сменить позже **Подключение с Mac:** 1. Finder → `⌘K` → `smb://192.168.1.14` 2. Логин: `timemachine` / `timemachine` 3. System Preferences → Time Machine → Add Disk → выбрать `kraken` Лог cron: `/var/log/timemachine-cron.log` --- ## Шаг 10 — Перенос данных ### Фильмы с Mac на NAS ```bash rsync -avh --progress /path/to/movies/ kraken@kraken.local:/srv/.../media/movies/ ``` ### Time Machine > ⚠️ Старый TM-бэкап перенести нельзя напрямую — TM привязывает бэкап к конкретному диску/хосту. > Начать новый бэкап на NAS, старый HDD хранить как архив или отформатировать после нескольких успешных новых бэкапов. --- ## Шаг 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 ``` ### Модели (актуально 2026-05-13) | Модель | Статус | |--------|--------| | `gemini-2.5-flash` | ✅ primary | | openrouter fallbacks | ✅ | ### Telegram бот - Имя: Кракен / Bot: [@kraken_htpc_bot](https://t.me/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` ### Деплой / пересборка ```bash # Сборка (осторожно — 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 (или запарить заново) - [ ] Проверить SD backup cron (первый запуск упал из-за SSH disconnect — воскресенье 03:00) --- ## Шаг 11а — Docker и containerd на HDD **Статус: ✅ (2026-05-13)** SD карта 14GB быстро заполняется Docker образами. Всё перенесено на HDD. ### Docker data-root ```bash # /etc/docker/daemon.json {"data-root": "/srv/dev-disk-by-uuid-49e8f586-3839-4c5d-a1e1-58bfc3579ade/docker-data"} ``` ### containerd → symlink на HDD ```bash 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:** - [ ] Создать `wiki/SCHEMA.md`, `wiki/index.md`, `wiki/log.md` - [ ] Добавить cron job на Eagle: ежедневно 02:00, skill `llm-wiki` - [ ] Настроить `WIKI_PATH=~/obsidian/wiki` в Eagle `.env` --- ## Уроки (что пошло не так при установке) - **Balena Etcher** не поддерживает OS Customisation — использовать только **RPi Imager** - **`userconf.txt`** deprecated на 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/