[2026-05-23] restore wiki: 32 files lost to Taiga sync bug; gitignore plugin binaries
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Arr Stack — Kraken
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [arr, radarr, sonarr, prowlarr, transmission, jellyfin, infra, kraken]
|
||||
related: "[[jellyfin-config]]"
|
||||
---
|
||||
|
||||
# Arr Stack — Kraken
|
||||
|
||||
## Pipeline
|
||||
|
||||
```
|
||||
Prowlarr → Radarr + Sonarr → Transmission → Jellyfin
|
||||
```
|
||||
|
||||
## API Keys
|
||||
|
||||
| Service | API Key |
|
||||
|-------------|----------------------|
|
||||
| Radarr | `cbcb8ec3...` |
|
||||
| Sonarr | `15fbec32...` |
|
||||
| Prowlarr | `134ac38a...` |
|
||||
|
||||
(Full keys truncated — retrieve from each service's settings page.)
|
||||
|
||||
## Ports (default Docker network)
|
||||
|
||||
All services accessible at `kraken:<port>`:
|
||||
|
||||
| Service | Port |
|
||||
|--------------|------|
|
||||
| Radarr | 7878 |
|
||||
| Sonarr | 8989 |
|
||||
| Prowlarr | 9696 |
|
||||
| Transmission | 9091 |
|
||||
| Jellyfin | 8096 |
|
||||
|
||||
## Notes
|
||||
|
||||
- See [[arr-stack-taiga]] for Taiga (secondary) arr stack
|
||||
- Media pipeline pitfalls: [[media-pipeline-pitfalls]]
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Arr Stack — Taiga
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [arr, taiga, infra, media, pitfalls]
|
||||
related: "[[arr-stack-kraken]]"
|
||||
---
|
||||
|
||||
# Arr Stack — Taiga
|
||||
|
||||
Secondary arr stack on Taiga (TrueNAS), added 2026-05-20.
|
||||
|
||||
## Notes from Setup (2026-05-20)
|
||||
|
||||
- Config and pitfalls recorded during initial Taiga arr stack deployment
|
||||
- `router.py` was customized — check `/mnt/RED_2TB/docker/arr-taiga/router.py`
|
||||
for current state
|
||||
|
||||
## Key Differences from Kraken Stack
|
||||
|
||||
- Taiga = TrueNAS host (storage-focused)
|
||||
- Kraken = Raspberry Pi 5 (playback-focused)
|
||||
- Taiga stack handles acquisition; Kraken handles serving to Jellyfin
|
||||
|
||||
## Pitfalls
|
||||
|
||||
(Details were referenced but not captured. Update this page after next
|
||||
Taiga arr maintenance session.)
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Gitea Config
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags: [infra, gitea, git, credentials]
|
||||
related: "[[kraken-network]]"
|
||||
---
|
||||
|
||||
# Gitea Config
|
||||
|
||||
**URL:** `http://git.mallexxx.duckdns.org` (external) / `http://172.16.3.4:3000` (internal LAN)
|
||||
**User:** `git_admin`
|
||||
|
||||
## API Token
|
||||
|
||||
Token name: `eagle-reflect`
|
||||
Token value: `f2e679a571f4c599d64b384a711043f995fd8844`
|
||||
|
||||
Used by Eagle for repo operations (push, PR creation, hook management).
|
||||
|
||||
## Notes
|
||||
|
||||
- External URL uses DuckDNS DDNS pointing to home IP
|
||||
- Internal API endpoint preferred when on home network
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Hermes Docker on Kraken
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags: [hermes, docker, kraken, infra, how-to]
|
||||
related: "[[kraken-network]]"
|
||||
---
|
||||
|
||||
# Hermes Docker on Kraken
|
||||
|
||||
## Key Rule
|
||||
|
||||
Hermes runs via **`docker run`**, NOT `docker compose`. No compose file.
|
||||
|
||||
## Launch Pattern
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name hermes \
|
||||
--restart unless-stopped \
|
||||
-v ~/.hermes:/root/.hermes \
|
||||
... \
|
||||
hermes-image:tag
|
||||
```
|
||||
|
||||
(Add actual flags from the running container: `docker inspect hermes`)
|
||||
|
||||
## Notes
|
||||
|
||||
- Using `docker run` keeps restart behavior explicit
|
||||
- No compose means no accidental `docker compose down` wipes it
|
||||
- Config/memory volume: `~/.hermes` on Kraken host
|
||||
@@ -0,0 +1,228 @@
|
||||
---
|
||||
title: Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
|
||||
type: reference
|
||||
namespace: work
|
||||
tags:
|
||||
- hermes
|
||||
- mac
|
||||
- eagle
|
||||
- claude-proxy
|
||||
- zulip
|
||||
- pitfalls
|
||||
created: '2026-05-21'
|
||||
updated: '2026-05-22'
|
||||
last_synced: '2026-05-22'
|
||||
confidence: 0.9
|
||||
---
|
||||
# Hermes на Eagle (Mac M4 Max) — Настройка и подводные камни
|
||||
|
||||
Hermes работает нативно (не в Docker) на Mac через `hermes gateway`.
|
||||
Транспорт — Zulip (запущен в Docker). Провайдер модели — openclaw-claude-proxy
|
||||
(см. ниже).
|
||||
|
||||
## Компоненты
|
||||
|
||||
| Компонент | Расположение | Запуск |
|
||||
|-----------|-------------|--------|
|
||||
| Hermes config | `~/.hermes/config.yaml` | — |
|
||||
| claude-proxy (Claude proxy) | `/opt/homebrew/bin/claude-proxy` | launchd `ai.claude-proxy` |
|
||||
| Zulip stack | `~/Developer/zulip/docker-compose.yml` | `docker compose up -d` |
|
||||
| Obsidian MCP | mcpvault | встроен в Hermes toolset |
|
||||
|
||||
---
|
||||
|
||||
## openclaw-claude-proxy — обход rate limit Claude API
|
||||
|
||||
### Проблема
|
||||
|
||||
`provider: claude-code` в Hermes использует OAuth-токен напрямую через
|
||||
API Anthropic — и упирается в rate limit подписки. Лимиты сбрасываются
|
||||
раз в час. API-ключа нет (политика организации).
|
||||
|
||||
### Почему не cmappy
|
||||
|
||||
cmappy (`claude-max-proxy-py`) молча выбрасывает поле `tools` из запроса —
|
||||
передаёт только текст в `claude --print`. Результат: Hermes не может
|
||||
использовать **ни один инструмент** (скиллы, MCP, терминал). Только голый
|
||||
чат.
|
||||
|
||||
### Решение: openclaw-claude-proxy
|
||||
|
||||
[mehdic/claude-proxy](https://github.com/mehdic/claude-proxy) (npm:
|
||||
`openclaw-claude-proxy`) — Node.js сервер, запускает `claude --print` как
|
||||
subprocess и предоставляет OpenAI-совместимый `/v1/chat/completions` на
|
||||
порту 3456. **Поддерживает tool_use** — инжектирует схемы инструментов в
|
||||
системный промпт, парсит JSON tool_call из ответа, возвращает стандартный
|
||||
OpenAI `tool_calls`. Caller (Hermes) сам выполняет инструменты.
|
||||
|
||||
**Важно:** `CLAUDE_PROXY_TOOLS_TRANSLATION=1` НЕ включать — этот режим
|
||||
выполняет MCP инструменты внутри CLI и Hermes ничего не получает.
|
||||
|
||||
### Установка
|
||||
|
||||
```bash
|
||||
npm install -g openclaw-claude-proxy
|
||||
```
|
||||
|
||||
### Wrapper-скрипт (обязателен для launchd)
|
||||
|
||||
`~/.local/bin/claude-proxy-start.sh`:
|
||||
```bash
|
||||
#!/bin/zsh
|
||||
# launchd не наследует среду login-сессии — токен нужно загружать явно
|
||||
set -a
|
||||
source /Users/admin/.hermes/.env 2>/dev/null
|
||||
set +a
|
||||
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
exec /opt/homebrew/bin/claude-proxy 3456
|
||||
```
|
||||
|
||||
**Pitfall:** без явного `source ~/.hermes/.env` claude-proxy не видит
|
||||
`CLAUDE_CODE_OAUTH_TOKEN` и прогревочные процессы падают с "Not logged in".
|
||||
|
||||
**Pitfall:** без явного PATH Claude CLI не найден (`/opt/homebrew/bin/claude`
|
||||
не в launchd PATH).
|
||||
|
||||
### launchd сервис
|
||||
|
||||
`~/Library/LaunchAgents/ai.claude-proxy.plist`:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key><string>ai.claude-proxy</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Users/admin/.local/bin/claude-proxy-start.sh</string>
|
||||
</array>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>HOME</key><string>/Users/admin</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/Users/admin/.hermes/logs/claude-proxy.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/Users/admin/.hermes/logs/claude-proxy.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
```bash
|
||||
launchctl load ~/Library/LaunchAgents/ai.claude-proxy.plist
|
||||
```
|
||||
|
||||
**Pitfall при перезагрузке:** если старый процесс ещё держит порт 3456:
|
||||
```bash
|
||||
lsof -ti :3456 | xargs kill -9
|
||||
launchctl unload ~/Library/LaunchAgents/ai.claude-proxy.plist
|
||||
launchctl load ~/Library/LaunchAgents/ai.claude-proxy.plist
|
||||
```
|
||||
|
||||
### Конфигурация Hermes
|
||||
|
||||
`~/.hermes/config.yaml` (секция model):
|
||||
```yaml
|
||||
model:
|
||||
default: claude-sonnet-4-6
|
||||
# provider: claude-code # отключён — упирается в rate limit OAuth API
|
||||
provider: custom
|
||||
base_url: 'http://localhost:3456/v1'
|
||||
```
|
||||
|
||||
**Pitfall:** `provider: openai` не существует в Hermes — нужно `custom`.
|
||||
|
||||
**Pitfall:** `base_url` должен включать `/v1` (Hermes дописывает
|
||||
`/chat/completions`). Без `/v1` → 404.
|
||||
|
||||
---
|
||||
|
||||
## Zulip Docker — подводные камни
|
||||
|
||||
### RabbitMQ: пользователи сбрасываются после перезапуска
|
||||
|
||||
**Симптом:** Zulip отдаёт 500 на `/api/v1/register`. В логах RabbitMQ —
|
||||
паника Khepri (Raft WAL). Пользователи в RabbitMQ исчезают.
|
||||
|
||||
**Причина:** RabbitMQ 4.x использует Khepri вместо Mnesia. При переполнении
|
||||
диска WAL не может записаться → Khepri сбрасывает состояние → пользователи
|
||||
исчезают. `RABBITMQ_DEFAULT_USER/PASS` применяются только при **первом
|
||||
старте** с пустым volume — повторный запуск их не восстанавливает.
|
||||
|
||||
**Решение:**
|
||||
|
||||
1. `docker system prune` — освободить место на диске (Docker VM sparse disk
|
||||
не освобождает место автоматически).
|
||||
2. Добавить `RABBITMQ_ERLANG_COOKIE` в env rabbitmq (стабилизирует cookie
|
||||
через перезапуски).
|
||||
3. При повреждённом volume — стереть и пересоздать:
|
||||
```bash
|
||||
docker compose down
|
||||
docker volume rm zulip_zulip-rabbitmq
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Log rotation (обязательно!)
|
||||
|
||||
Без ротации логи заполняют Docker VM (~6 ГБ за несколько месяцев).
|
||||
|
||||
`docker-compose.yml` — добавить к каждому сервису:
|
||||
```yaml
|
||||
# zulip:
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "50m"
|
||||
max-file: "5"
|
||||
|
||||
# rabbitmq, memcached, redis:
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "20m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
### Docker VM sparse disk
|
||||
|
||||
Mac Docker Desktop использует sparse virtual disk. Место, освобождённое
|
||||
внутри VM, не возвращается хосту автоматически. `docker system prune`
|
||||
запускает compaction.
|
||||
|
||||
---
|
||||
|
||||
## Obsidian MCP
|
||||
|
||||
Везде используется `mcpvault` (не `obsidian-mcp`).
|
||||
|
||||
| Конфиг | Путь |
|
||||
|--------|------|
|
||||
| Claude Code CLI | `~/.claude/.mcp.json` |
|
||||
| Claude Desktop App | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
||||
| Hermes | встроен через toolset |
|
||||
|
||||
Пример конфига (одинаковый для обоих):
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"obsidian": {
|
||||
"command": "mcpvault",
|
||||
"args": ["/Users/admin/obsidian"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pitfall:** `obsidian-mcp` (npm) был удалён — если остался в конфиге,
|
||||
Claude падает с "Failed to spawn process". Проверить логи:
|
||||
`~/Library/Logs/Claude/mcp-server-obsidian.log`.
|
||||
|
||||
---
|
||||
|
||||
## Связанные страницы
|
||||
|
||||
- [[tech/hermes-docker-kraken]] — Hermes на Кракене (Docker)
|
||||
- [[tech/kraken-network]] — сетевая топология
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: HTPC Kodi Layout & WoL
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [htpc, kodi, wol, infra, how-to]
|
||||
related: "[[htpc-steam-emulators]]"
|
||||
---
|
||||
|
||||
# HTPC Kodi Layout & WoL
|
||||
|
||||
## Wake on LAN
|
||||
|
||||
HTPC MAC address stored in router DHCP config. WoL command:
|
||||
|
||||
```bash
|
||||
wakeonlan <HTPC-MAC>
|
||||
```
|
||||
|
||||
Or via Kodi remote / Home Assistant automation.
|
||||
|
||||
## Kodi Layout
|
||||
|
||||
- Home screen: custom skin (record actual skin name here)
|
||||
- Sources: NFS mounts from TrueNAS (`/mnt/RED_2TB/...`)
|
||||
- Add-ons: check Kodi installed add-ons list
|
||||
|
||||
Note: specific layout details were not migrated. Update this page
|
||||
when next doing HTPC maintenance.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: HTPC Steam & Emulators
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [htpc, steam, emulators, gamepad, how-to]
|
||||
related: "[[htpc-kodi-layout]]"
|
||||
---
|
||||
|
||||
# HTPC Steam & Emulators
|
||||
|
||||
Bazzite HTPC at `192.168.1.86`. See [[htpc-bazzite-proton]] for Proton
|
||||
game compatibility details.
|
||||
|
||||
## Rules
|
||||
|
||||
- Game save paths: managed per-emulator; see emulator config in Bazzite
|
||||
- Gamepad config: stored in Steam controller profiles, backed up to
|
||||
`~/controller-profiles/`
|
||||
- Steam shortcuts for non-Steam Windows games: use Proton Experimental
|
||||
|
||||
## Save Locations (approximate)
|
||||
|
||||
| System | Path |
|
||||
|--------|------|
|
||||
| Steam | `~/.steam/steam/userdata/` |
|
||||
| RetroArch | `~/.var/app/org.libretro.RetroArch/config/retroarch/saves/` |
|
||||
|
||||
Note: this file was reconstructed from a pointer — add specific paths
|
||||
as discovered.
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Jellyfin Config
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [jellyfin, infra, media, credentials]
|
||||
related: "[[arr-stack-kraken]]"
|
||||
---
|
||||
|
||||
# Jellyfin Config
|
||||
|
||||
**URL:** `http://kraken:8096`
|
||||
|
||||
## Users
|
||||
|
||||
| User | Password | Notes |
|
||||
|------|----------|-------|
|
||||
| alex | (set) | Admin |
|
||||
| lisa | (none) | Cartoons library only |
|
||||
|
||||
## API Key
|
||||
|
||||
`87af49b6ff62ea68da6abdab0d7a4fbc`
|
||||
|
||||
Used by automation scripts (watchlist-sync, media-pipeline agents).
|
||||
|
||||
## Database / Maintenance
|
||||
|
||||
- **Before any DB operation:** `docker stop jellyfin` first
|
||||
- Jellyfin runs as a Docker container on Kraken
|
||||
- Config stored in `/opt/jellyfin/config/` (check docker-compose for exact path)
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: Jellyfin Транскод на RPi5 — PGS/Subtitle Pitfalls
|
||||
type: reference
|
||||
namespace: work
|
||||
tags:
|
||||
- jellyfin
|
||||
- kraken
|
||||
- transcode
|
||||
- subtitles
|
||||
- pitfalls
|
||||
created: '2026-05-18'
|
||||
updated: '2026-05-18'
|
||||
---
|
||||
# Jellyfin Транскод на RPi5 — PGS/Subtitle Pitfalls
|
||||
|
||||
## Контекст
|
||||
|
||||
Клиент: Konka TV с WebOS. Сервер: Raspberry Pi 5 (Крaken, ARM64).
|
||||
|
||||
## Direct Play условия
|
||||
|
||||
Direct Play работает при выполнении всех условий:
|
||||
- Аудио: AAC
|
||||
- Субтитры: **отсутствуют** (или внешние SRT, без burn-in)
|
||||
|
||||
## Проблема PGS/ASS субтитров
|
||||
|
||||
PGS и ASS (SSA) субтитры вызывают **burn-in** — Jellyfin рендерит субтитры прямо в видеопоток.
|
||||
|
||||
**Результат:** полный транскод на CPU → **275% CPU load** на RPi5 → лаги, перегрев.
|
||||
|
||||
**Экспериментальный PGS rendering** в настройках Jellyfin — **не помогает** на RPi5.
|
||||
|
||||
## Решение: конвертация PGS → SRT
|
||||
|
||||
Установка через uv (arm64/aarch64 совместимо):
|
||||
```bash
|
||||
~/.local/bin/uv tool install pgsrip
|
||||
sudo apt-get install -y libgl1 libglib2.0-0 tesseract-ocr tesseract-ocr-rus tesseract-ocr-eng
|
||||
```
|
||||
|
||||
Скрипт конвертации:
|
||||
```
|
||||
/srv/dev-disk-by-uuid.../docker/media-pipeline/pgs-to-srt.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
# один файл
|
||||
pgs-to-srt.sh /media/movies/Film.mkv
|
||||
|
||||
# вся директория
|
||||
pgs-to-srt.sh /media
|
||||
```
|
||||
|
||||
Логи: `/srv/.../docker/media-pipeline/pgs-to-srt.log`
|
||||
|
||||
Скрипт:
|
||||
- Скипает файлы без PGS-дорожек (S_HDMV)
|
||||
- Скипает если .srt уже есть рядом
|
||||
- Пишет лог с timestamp
|
||||
|
||||
После конвертации Jellyfin читает внешние `.srt` без транскода.
|
||||
|
||||
## Transmission completion hook
|
||||
|
||||
Хук `/config/on-download-complete.sh` (монтируется в контейнер `:ro`) после завершения загрузки:
|
||||
1. Запускает media-pipeline sync
|
||||
2. Запускает pgs-to-srt.sh для скачанного файла/директории
|
||||
|
||||
Лог: `/srv/.../docker/media-pipeline/download-complete.log`
|
||||
|
||||
## Итог по субтитрам
|
||||
|
||||
| Тип | Direct Play | Транскод |
|
||||
|-----|------------|---------|
|
||||
| Нет субтитров | ✅ | — |
|
||||
| Внешний SRT | ✅ | — |
|
||||
| ASS/SSA | ❌ | burn-in, 275% CPU |
|
||||
| PGS (MKS/MKV) | ❌ | burn-in, 275% CPU |
|
||||
|
||||
## NFD/NFC filename encoding pitfall
|
||||
|
||||
**Проблема:** HTPC сохраняет имена файлов в NFD, Kraken — в NFC.
|
||||
→ Jellyfin видит **две** папки: одна с `.avi` файлом (NFD), другая с `.nfo` (NFC).
|
||||
→ NFO не применяется — Jellyfin берёт NFD-папку (с видео) и игнорирует NFC-папку (с NFO).
|
||||
→ Метаданные пустые.
|
||||
|
||||
**Фикс A (быстрый):** скопировать `movie.nfo` + `poster.jpg` в NFD-папку:
|
||||
```bash
|
||||
# python3 — использовать bytes для путей
|
||||
import os, shutil
|
||||
nfc_path = "…/Movie.NFC/movie.nfo"
|
||||
nfd_path = "…/Movie.NFD/movie.nfo"
|
||||
shutil.copy(nfc_path.encode(), nfd_path.encode())
|
||||
```
|
||||
|
||||
**Фикс B (радикальный):** переименовать всё в NFC (нормализовать).
|
||||
|
||||
**Диагностика:**
|
||||
```bash
|
||||
ls -la | cat -v # покажет NFD-escape символы как ^ escape sequences
|
||||
python3 -c "import os; [print(repr(f)) for f in os.listdir('.')]"
|
||||
```
|
||||
|
||||
## Связанные страницы
|
||||
|
||||
- [[concepts/kraken-media-stack]] — полный медиастек: *arr + Jellyfin + media-pipeline
|
||||
- [[tech/kraken-network]] — инфра Кракена, HDD error recovery
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Kraken Network & Infra
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags: [infra, kraken, ssh, wireguard, network]
|
||||
related: "[[arr-stack-kraken]]"
|
||||
---
|
||||
|
||||
# Kraken Network & Infra
|
||||
|
||||
## SSH Access
|
||||
|
||||
```
|
||||
ssh kraken
|
||||
```
|
||||
|
||||
IP: `192.168.1.15` (wlan0, primary). SSH alias `kraken` resolves via `~/.ssh/config`.
|
||||
|
||||
## WireGuard Topology
|
||||
|
||||
Split-tunnel: Eagle ↔ VPS ↔ Kraken. Full details: [[tech/wireguard-vpn]].
|
||||
|
||||
- Eagle: `10.99.0.2`, Kraken: `10.99.1.2`, VPS relay: `10.99.0.1`/`10.99.1.1`
|
||||
- `wg-auto.sh` on Eagle (LaunchDaemon) — up when off home Wi-Fi, down at home
|
||||
- VPS as relay; two interfaces (wg0/wg1) avoid hairpin forwarding
|
||||
|
||||
## Media Volume Mount Paths
|
||||
|
||||
Docker containers on Kraken mount media from NAS over NFS/SMB.
|
||||
Paths were documented here — check docker-compose files in
|
||||
`/opt/media-toolbox-kraken` for current mount config.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Media Pipeline Pitfalls
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [media-pipeline, pitfalls, torrents, infra]
|
||||
related: "[[arr-stack-kraken]]"
|
||||
---
|
||||
|
||||
# Media Pipeline Pitfalls
|
||||
|
||||
## Torrents — Do Not Rename Files
|
||||
|
||||
Never rename torrent source files or folders while a torrent is active.
|
||||
Transmission tracks files by path. Renaming breaks the association and
|
||||
causes re-download or stalled seeding.
|
||||
|
||||
## torrent-set-location Updates downloadDir
|
||||
|
||||
`torrent-set-location` in the Transmission RPC updates `downloadDir` in
|
||||
the torrent metadata. Use this when moving completed files, not a manual
|
||||
rename. Sequence:
|
||||
|
||||
1. Move files to new location on disk
|
||||
2. Call `torrent-set-location` with the new path + `move=false`
|
||||
3. Verify torrent goes back to seeding state
|
||||
|
||||
## General Rules
|
||||
|
||||
- Never touch source files/folders (media-pipeline USER.md rule)
|
||||
- `resolve-manual` is emergency-only
|
||||
- NFO files: do not create manually; let the pipeline handle them
|
||||
- Never delete test files from the pipeline project
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Reflect — Skip Fuse (SwiftUI/Kotlin)
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags: [reflect, swift, kotlin, ios, android, pitfalls]
|
||||
related: "[[kraken-network]]"
|
||||
---
|
||||
|
||||
# Reflect — Skip Fuse (SwiftUI/Kotlin)
|
||||
|
||||
## Key Pitfall
|
||||
|
||||
When adding a **new SwiftUI View** to the Reflect iOS codebase, Skip Fuse
|
||||
does **not** auto-generate the Kotlin counterpart. A manual Kotlin stub is
|
||||
required in **2 places**:
|
||||
|
||||
1. The View class file in the Android module
|
||||
2. The registration/factory in the Android navigation/router
|
||||
|
||||
## Why
|
||||
|
||||
Skip Fuse transpiles shared SwiftUI code to Kotlin, but new View types
|
||||
require explicit Kotlin stubs until Skip's transpilation coverage catches up.
|
||||
|
||||
## Checklist for New SwiftUI Views
|
||||
|
||||
- [ ] Add SwiftUI view as normal in iOS target
|
||||
- [ ] Create matching Kotlin stub in `android/src/.../views/`
|
||||
- [ ] Register in Android router/factory
|
||||
- [ ] Run `./gradlew build` to verify no missing class errors
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: TrueNAS Inpxer / Books Setup
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: family
|
||||
tags: [truenas, books, infra, storage]
|
||||
related: "[[kraken-network]]"
|
||||
---
|
||||
|
||||
# TrueNAS Inpxer / Books Setup
|
||||
|
||||
## Books Storage Path
|
||||
|
||||
```
|
||||
/mnt/RED_2TB/storage/books/
|
||||
```
|
||||
|
||||
Books are stored on the RED_2TB pool. Inpxer (or similar indexer) serves
|
||||
the library from this location.
|
||||
|
||||
## Related TrueNAS Notes
|
||||
|
||||
- General TrueNAS access: [[family/how-to/truenas-access]]
|
||||
- Remote access reverse proxy: [[personal/docs/truenas-remote-access-reverse-proxy]]
|
||||
- Rclone backup: [[family/how-to/truenas-rclone-backup]]
|
||||
|
||||
Note: Inpxer-specific config was not migrated — add details here when
|
||||
revisiting this setup.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: Vault Namespace Rules
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags: [vault, meta, conventions]
|
||||
related: "[[kraken-network]]"
|
||||
---
|
||||
|
||||
# Vault Namespace Rules
|
||||
|
||||
Rules for where notes live in the Obsidian vault. See also [[SCHEMA]] for
|
||||
full frontmatter conventions.
|
||||
|
||||
## Namespace Assignments
|
||||
|
||||
- `personal`: Eagle infra, personal projects, dev tooling
|
||||
- `family`: Kraken media stack, HTPC, Jellyfin, family content
|
||||
- `work`: DuckDuckGo / DDG tasks and tooling
|
||||
|
||||
## Directory Map
|
||||
|
||||
```
|
||||
wiki/concepts/ — how-it-works explanations
|
||||
wiki/tech/ — infra how-tos, tool configs, pitfalls
|
||||
wiki/ideas/ — speculative, not yet decided
|
||||
personal/projects/ — project status & decisions
|
||||
family/projects/ — family-shared project status
|
||||
family/how-to/ — family infra procedures
|
||||
```
|
||||
|
||||
Note: this file was reconstructed from a lost pointer. Extend with actual
|
||||
rules as they emerge.
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: WireGuard VPN — Eagle to Kraken
|
||||
created: '2026-05-23'
|
||||
updated: '2026-05-23'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags: [infra, kraken]
|
||||
sources: [family/how-to/wireguard-vpn.md]
|
||||
confidence: high
|
||||
---
|
||||
|
||||
# WireGuard VPN — Eagle to Kraken
|
||||
|
||||
Split-tunnel VPN connecting Eagle (Mac M4, home) to Kraken (RPi5, home) via
|
||||
a VPS relay. Enables SSH to Kraken from anywhere and routes Time Machine
|
||||
backups over the tunnel. Two VPS interfaces avoid hairpin forwarding.
|
||||
|
||||
## Topology
|
||||
|
||||
```
|
||||
Eagle (10.99.0.2) ←→ wg0 VPS (10.99.0.1) ←→ wg1 VPS (10.99.1.1) ←→ Kraken (10.99.1.2)
|
||||
:51820 :51821
|
||||
```
|
||||
|
||||
SNAT rewrites source address: Eagle packets arrive at Kraken with src
|
||||
`10.99.1.1` (VPS wg1), not Eagle's `10.99.0.2`. FORWARD runs wg0→wg1
|
||||
on the VPS with nftables.
|
||||
|
||||
## VPN Addresses
|
||||
|
||||
| Node | VPN IP |
|
||||
|------|--------|
|
||||
| VPS wg0 | 10.99.0.1 |
|
||||
| VPS wg1 | 10.99.1.1 |
|
||||
| Eagle | 10.99.0.2 |
|
||||
| Kraken | 10.99.1.2 |
|
||||
|
||||
`kraken` hostname resolves via dnsmasq on VPS (`DNS = 10.99.0.1` in Eagle's
|
||||
wg0.conf). DNS is scoped to the `kraken` domain only (see DNS section).
|
||||
|
||||
## Persistence
|
||||
|
||||
| Component | Node | How it survives reboot |
|
||||
|-----------|------|------------------------|
|
||||
| wg-quick@wg0 + wg-quick@wg1 | VPS | systemd enabled |
|
||||
| PostUp FORWARD + SNAT rules | VPS | embedded in `/etc/wireguard/wg0.conf` |
|
||||
| nftables (10.99.0.0/16 forward) | VPS | `/etc/nftables.conf`, systemd enabled |
|
||||
| dnsmasq (`kraken` → 10.99.1.2) | VPS | `/etc/dnsmasq.d/vpn-hosts.conf`, systemd enabled |
|
||||
| wg-quick@wg0 | Kraken | systemd enabled |
|
||||
| wg-auto LaunchDaemon | Eagle | `/Library/LaunchDaemons/top.eagle.wg-auto.plist` |
|
||||
|
||||
## Auto-Connect on Eagle
|
||||
|
||||
`/usr/local/bin/wg-auto.sh` polls every 30 seconds via launchd
|
||||
(`StartInterval`, **not** WatchPaths):
|
||||
|
||||
- At home (router MAC `f0:79:59:77:9b:70` visible on ARP) → `wg-quick down`
|
||||
- Off home network → `wg-quick up`
|
||||
|
||||
**Why StartInterval and not WatchPaths:** WatchPaths triggered a race —
|
||||
`wg-quick down` changes DNS via `networksetup`, which writes to
|
||||
`/Library/Preferences/SystemConfiguration/`, which re-fires launchd,
|
||||
tearing the tunnel down immediately after connecting.
|
||||
|
||||
## DNS (Scoped Resolver)
|
||||
|
||||
wg0.conf uses **no global `DNS =`**. PostUp/PostDown manage a
|
||||
macOS scoped resolver for the `kraken` domain only:
|
||||
|
||||
```
|
||||
PostUp = mkdir -p /etc/resolver && \
|
||||
echo "nameserver 10.99.0.1" > /etc/resolver/kraken && \
|
||||
killall -HUP mDNSResponder
|
||||
PostDown = rm -f /etc/resolver/kraken && killall -HUP mDNSResponder
|
||||
```
|
||||
|
||||
Result: only `kraken` resolves via VPS dnsmasq. Global DNS and Wi-Fi IP
|
||||
are untouched — prevents address-bar breakage during tunnel transitions.
|
||||
|
||||
## Time Machine
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Old destination (broken) | `smb://timemachine@kraken._smb._tcp.local./TimeMachine` |
|
||||
| New destination (working) | `smb://timemachine@kraken/TimeMachine` |
|
||||
|
||||
mDNS (`_smb._tcp.local`) doesn't work off the local LAN. VPN DNS (`kraken`
|
||||
→ 10.99.1.2 via dnsmasq) works from anywhere. Container on Kraken:
|
||||
`mbentley/timemachine:smb`, `restart: unless-stopped`.
|
||||
|
||||
## Public Keys
|
||||
|
||||
| Node | Public Key |
|
||||
|------|------------|
|
||||
| VPS wg0 | `6W6hSw0JFLm0BbyeNp1g7wF7dKKTZmGvPRdir68mz0w=` |
|
||||
| VPS wg1 | `ssRV2497NQ3Lfzvx/FLO0jDlcCXdK/RReJQ36i0yuR8=` |
|
||||
| Eagle | `dDgIjBUNguodOHWoz7iFsImvKhteodHcFWM8mMe4UiE=` |
|
||||
| Kraken | `8kIdCKMIoMsW09/aQX6+pU0SS/rN4PysJL59w17eGRg=` |
|
||||
|
||||
## Diagnostics
|
||||
|
||||
```bash
|
||||
# Eagle — check tunnel state
|
||||
sudo wg show
|
||||
ping kraken
|
||||
|
||||
# VPS
|
||||
ssh root@91.207.28.205 "wg show all"
|
||||
|
||||
# Kraken
|
||||
ssh kraken "sudo wg show"
|
||||
|
||||
# Eagle auto-connect log
|
||||
cat /var/log/wg-auto.log
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [[tech/kraken-network]] — Kraken SSH access, media volume paths
|
||||
- [[personal-os-architecture]] — Eagle hardware, home infra overview
|
||||
Reference in New Issue
Block a user