Remove deprecated files related to homelab architecture, container context, and various scripts. This cleanup includes the removal of configuration files for Nextcloud, Gitea, and VPN setups, as well as documentation files that are no longer relevant. This helps streamline the project and eliminate outdated references.

This commit is contained in:
2026-02-25 17:03:10 +03:00
parent 3c00fbf67b
commit b0d2746490
74 changed files with 2662 additions and 7107 deletions

View File

@@ -0,0 +1,258 @@
# Контейнер 100 (nginx): NPM, Homepage, AdGuard, Wallos и сопутствующие сервисы
Подробное описание LXC-контейнера **100** на Proxmox (192.168.1.100): reverse proxy, DNS-фильтрация, дашборд, учёт подписок, мониторинг логов и маршрутов VPN.
---
## Общие сведения
- **Хостнейм:** nginx
- **IP:** 192.168.1.100/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 1 core, 2 GB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 100 -- bash` или `ssh` на 192.168.1.100, если настроен.
Диск контейнера: порядка 10 GB, занято ~4.6 GB (логи и данные сервисов). Следить за местом (см. раздел «Логи и ротация» и TODO).
---
## Доступ и логины
- **Debian (CT 100):** логин `root` (или консольный пользователь Debian), пароль `waccEk-fyqbux-rarja3`.
- **AdGuard Home:** http://192.168.1.100:3000, пользователь `kerrad`, пароль `waccEk-fyqbux-rarja3`.
- **Nginx Proxy Manager:** http://192.168.1.100:81, имя `Kerrad`, email `j3tears100@gmail.com`, пароль `kqEUubVq02DJTS8`.
- **Wallos:** https://wallos.katykhin.ru (через NPM), Webлогин/пароль сохранены в менеджере паролей; Basic Auth в NPM — логин `admin`, пароль `fy8lNlWvvJryfrUVMZr8`.
- **Homepage:** https://home.katykhin.ru, логин `admin`, пароль `fy8lNlWvvJryfrUVMZr8`.
---
## Сервисы (Docker)
Все сервисы запущены в Docker. Сети: **proxy_network** (общая для NPM, Homepage, Wallos, dockerproxy, AdGuard), **adguard_proxy_network** (AdGuard дополнительно). Контейнер **vpn-route-check** в режиме `network_mode: host`.
| Контейнер | Образ | Порты (хост) | Назначение |
|-------------------|------------------------------------|-------------------|------------|
| npm | jc21/nginx-proxy-manager:latest | 80, 81, 443 | Reverse proxy, SSL, админка NPM |
| adguard | adguard/adguardhome:latest | 53/tcp+udp, 6768, 853, 3000 | DNS, DoT, веб-интерфейс, опционально DHCP |
| homepage | ghcr.io/gethomepage/homepage:latest| 4000→3000 | Дашборд сервисов (home.katykhin.ru) |
| dockerproxy | tecnativa/docker-socket-proxy | 2375 (внутри сети)| Прокси к Docker API для Homepage (только чтение) |
| wallos | bellamy/wallos:latest | 8282→80 | Учёт подписок (wallos.katykhin.ru) |
| log-dashboard | nginx:alpine | 8088→80 | Просмотр ленты обращений NPM (статика из html) |
| vpn-route-check | свой образ (build) | host | Проверка маршрутов VPN по доменам, дашборд на 8765 |
---
## 1. Nginx Proxy Manager (NPM)
**Каталог:** `/opt/docker/nginx-proxy/`
**Compose:** `docker-compose.yml` (образ `jc21/nginx-proxy-manager:latest`, restart unless-stopped).
**Порты:** 80 (HTTP), 81 (админка), 443 (HTTPS).
**Тома:**
- `./data``/data` (конфиги nginx, БД SQLite, логи, custom_ssl, proxy_host)
- `./letsencrypt``/etc/letsencrypt` (в контейнере; с хоста certbot пишет в системный `/etc/letsencrypt`, см. ниже).
**Сеть:** proxy_network.
**Основные пути на хосте:**
- `/opt/docker/nginx-proxy/data/` — данные NPM (в т.ч. `nginx/proxy_host/*.conf`, `logs/`, `custom_ssl/`, `database.sqlite`).
- `/opt/docker/nginx-proxy/data/logs/` — логи nginx: `proxy-host-*_access.log`, `proxy-host-*_error.log`, `fallback_http_access.log`, `fallback_http_error.log`, `letsencrypt.log` и др.
- `/opt/docker/nginx-proxy/letsencrypt/` — копия/симлинки сертификатов для контейнера (56 KB); основные сертификаты выпускаются certbot на хосте в `/etc/letsencrypt/live/<домен>/` и при продлении копируются в NPM (custom_ssl) через deploy-hook.
**Certbot на хосте (внутри CT 100):**
- Установлен в системе, таймер `certbot.timer` (проверка продления дважды в день).
- Учётные данные Beget API: `/root/.secrets/certbot/beget.ini`.
- Deploy-hookи: `/etc/letsencrypt/renewal-hooks/deploy/` — скрипты `copy-*-to-npm.sh` (video, docs, immich, mini-lm и т.д.) копируют `fullchain.pem` и `privkey.pem` в соответствующий каталог `custom_ssl/npm-<id>/` и делают `docker exec npm nginx -s reload`.
Подробнее по SSL: [Выпуск сертификата Let's Encrypt (DNS-01)](../network/ssl-letsencrypt-dns01.md).
**Команды:**
```bash
docker logs npm
docker exec npm nginx -s reload
```
---
## 2. AdGuard Home
**Каталог:** `/opt/docker/adguard/`
**Compose:** `docker-compose.yml` (образ `adguard/adguardhome:latest`).
**Порты:** 53 (DNS TCP/UDP), 6768 (DHCP при необходимости), 853 (DoT), 3000 (веб-интерфейс).
**Тома:** `./data/work`, `./data/conf` → соответствующие пути в контейнере.
**Сеть:** adguard_proxy_network и proxy_network (доступ с NPM по имени `adguard`).
**Конфиг:** `/opt/docker/adguard/data/conf/AdGuardHome.yaml` (upstream DNS, кэш, привязки, пользователи и т.д.). Данные и кэш: `data/work/`.
Доступ в веб: http://192.168.1.100:3000. В NPM настроен proxy на adguard (в т.ч. для adguard.local). Виджет и пароль для Homepage задаются в `services.yaml` (в контейнере).
**Команды:**
```bash
docker logs adguard
docker restart adguard
```
---
## 3. Homepage
**Каталог:** `/opt/docker/homepage/config/`
**Compose:** в `/opt/docker/homepage/docker-compose.yml` (homepage + dockerproxy).
**Порты:** 4000 (хост) → 3000 (контейнер).
**Тома:** `./config``/app/config`, `./config/images``/app/public/images`.
**Переменные:** `TZ=Europe/Moscow`, `HOMEPAGE_ALLOWED_HOSTS=home.katykhin.ru`, `DOCKER_HOST=tcp://dockerproxy:2375`.
**Сеть:** proxy_network.
**Основные файлы конфигурации:**
- `services.yaml` — список сервисов, виджеты (NPM, AdGuard, Proxmox и др.), ссылки, пинги. Пароли и токены виджетов хранятся здесь (не коммитить в открытый репозиторий).
- `docker.yaml` — подключение к Docker через dockerproxy (host/port).
- `settings.yaml`, `widgets.yaml`, `bookmarks.yaml`, `custom.css`, `proxmox.yaml`, `kubernetes.yaml` при необходимости.
Логи Homepage: `/opt/docker/homepage/config/logs/` (~588 KB).
**Команды:**
```bash
cd /opt/docker/homepage && docker compose up -d
docker logs homepage
```
---
## 4. Docker Socket Proxy (dockerproxy)
Запускается из того же compose, что и Homepage. Даёт Homepage доступ к Docker API только на чтение (CONTAINERS, SERVICES, TASKS, IMAGES, INFO, NETWORKS, VOLUMES; POST=0). Сокет хоста монтируется read-only. Отдельных конфигов нет.
---
## 5. Wallos
**Каталог:** `/opt/docker/wallos/`
**Compose:** `docker-compose.yml` (образ `bellamy/wallos:latest`).
**Порты:** 8282 (хост) → 80 (контейнер).
**Тома:** `./db``/var/www/html/db`.
**Сеть:** proxy_network. Доступ через NPM: https://wallos.katykhin.ru (с Basic Auth в NPM).
**Команды:**
```bash
docker logs wallos
docker restart wallos
```
---
## 6. Log-dashboard (лента обращений NPM)
Показывает обработанные access-логи NPM в виде ленты с фильтрацией по домену и геолокацией.
- **Контейнер:** `log-dashboard`, образ `nginx:alpine`, порт **8088** (хост) → 80.
- **Том:** `/opt/docker/log-dashboard/html``/usr/share/nginx/html` (только чтение). Контейнер отдаёт статический HTML.
- **Генерация контента:** на **хосте** (внутри CT 100) по крону каждые **15 минут** выполняется:
```bash
python3 /opt/docker/log-dashboard/gen-dashboard.py /opt/docker/log-dashboard/html/index.html
```
Скрипт читает логи из `/opt/docker/nginx-proxy/data/logs/`, парсит access-формат NPM, добавляет геолокацию (ip-api.com, кэш в `ip_cache.json`), пишет результат в `index.html`.
- **Cron:** запись в crontab root: `*/15 * * * * ... gen-dashboard.py ...`.
Доступ: http://192.168.1.100:8088 (или через NPM, если настроен proxy). Контейнер запускается отдельно (не из общего compose в каталогах выше — при перезагрузке CT нужно проверить, что он поднят).
---
## 7. VPN Route Check
**Каталог:** `/opt/docker/vpn-route-check/`
**Compose:** `docker-compose.yml` (сборка своего образа, `network_mode: host`).
Проверяет, идут ли запросы к заданным доменам через VPN или через основное подключение (подключение к роутеру по telnet, разбор маршрутов). Результаты отдаёт на порту **8765** (на хосте). В Homepage добавлена ссылка на http://192.168.1.100:8765.
**Переменные окружения в compose:** `ROUTER_TELNET_HOST`, `ROUTER_TELNET_USER`, `ROUTER_TELNET_PASSWORD` — **заданы в самом файле** (не в .env). Рекомендация: вынести в `.env` и не коммитить пароль (см. TODO).
**Том:** volume `vpn-route-check-data` → `/data` (в контейнере).
**Команды:**
```bash
cd /opt/docker/vpn-route-check && docker compose up -d
docker logs vpn-route-check
```
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|-------|----------------------------|
| 80 | NPM (HTTP) |
| 81 | NPM (админка) |
| 443 | NPM (HTTPS) |
| 53 | AdGuard (DNS TCP/UDP) |
| 6768 | AdGuard (DHCP при необходимости) |
| 853 | AdGuard (DoT) |
| 3000 | AdGuard (веб) |
| 4000 | Homepage |
| 8088 | Log-dashboard |
| 8282 | Wallos |
| 8765 | VPN Route Check (host) |
---
## Логи и ротация
- **NPM:** логи в `/opt/docker/nginx-proxy/data/logs/`.
- Для файлов **proxy-host-*_access.log** настроен logrotate: `/etc/logrotate.d/npm-access` — ротация при 100 MB, 4 копии, copytruncate, compress.
- Файлы **fallback_http_access.log**, **fallback_http_error.log** и другие **fallback_*** в правиле не указаны** — ротация по размеру/времени для них не настроена, каталог уже ~67 MB. Риск разрастания (см. TODO).
- **Certbot:** `/etc/logrotate.d/certbot` — ротация логов letsencrypt (weekly, 12 копий).
- **AdGuard:** данные и логи в `data/work/` и `data/conf/` (~85 MB). Стоит проверить настройки хранения логов запросов в веб-интерфейсе AdGuard (ограничение по времени/размеру).
- **Homepage:** небольшие логи в `config/logs/`.
---
## Запуск и порядок поднятия
1. Создать сеть (если ещё нет): `docker network create proxy_network`.
2. NPM: `cd /opt/docker/nginx-proxy && docker compose up -d`.
3. AdGuard: `cd /opt/docker/adguard && docker compose up -d` (создаёт свою сеть и подключается к proxy_network).
4. Homepage (+ dockerproxy): `cd /opt/docker/homepage && docker compose up -d`.
5. Wallos: `cd /opt/docker/wallos && docker compose up -d`.
6. VPN Route Check: `cd /opt/docker/vpn-route-check && docker compose up -d`.
7. Log-dashboard: при необходимости запустить контейнер с монтом html и портом 8088.
После изменений в NPM (proxy, SSL): перезагрузка nginx внутри контейнера — `docker exec npm nginx -s reload`. Certbot продлевает сертификаты по таймеру; deploy-hookи копируют их в NPM и перезагружают nginx.
---
## Уязвимости и риски
1. **Пароли и креды в конфигах:** В `services.yaml` (Homepage) хранятся пароли виджетов (AdGuard, NPM, Proxmox). Файл лежит только на сервере; не помещать в публичный репозиторий.
2. **VPN Route Check:** Логин и пароль роутера прописаны в `docker-compose.yml`. Доступ к compose = доступ к роутеру. Рекомендуется вынести в `.env` и ограничить права на файл.
3. **AdGuard на 3000:** Веб-интерфейс доступен по порту 3000 на хосте. Доступ из LAN; при необходимости закрыть фаерволом снаружи или использовать только через NPM (proxy).
4. **NPM на 81:** Админка NPM по порту 81. Убедиться, что с интернета доступ только через VPN или не пробрасывать 81 наружу.
5. **Логи NPM:** Часть логов (fallback_*) не ротируется — возможен рост и заполнение диска (см. TODO).
---
## TODO по контейнеру 100
- [ ] **Логи NPM:** Добавить в logrotate ротацию для `fallback_http_access.log`, `fallback_http_error.log` (и при необходимости других fallback_*) по размеру или по дням, чтобы не забивать диск.
- [ ] **Логи AdGuard:** Проверить в веб-интерфейсе AdGuard настройки хранения логов запросов (срок/размер) и при необходимости ограничить.
- [ ] **VPN Route Check:** Вынести `ROUTER_TELNET_*` в `.env`, подключать в compose через `env_file`, не коммитить .env в репозиторий.
- [ ] **Log-dashboard:** Зафиксировать способ запуска контейнера (отдельный compose или скрипт) и добавить его в документацию/автозапуск при перезагрузке CT.
- [ ] **Мониторинг диска:** Настроить оповещение (например, из Prometheus/Alertmanager или скрипт по крону) при заполнении корня или `/opt/docker` выше порога (например 80%).
- [ ] **Резервное копирование:** Регулярный бэкап критичных папок (оценка размеров на момент документации):
- `/opt/docker/nginx-proxy/data` — ~68 MB (конфиги NPM, БД, логи, custom_ssl).
- `/opt/docker/adguard/data` — ~85 MB (конфиги и данные AdGuard).
- `/opt/docker/homepage/config` — ~0.7 MB (конфиги Homepage).
- `/opt/docker/wallos/db` — ~0.2 MB (БД Wallos).
- `/opt/docker/vpn-route-check` — ~0.1 MB (скрипты и конфиг).
- `/etc/letsencrypt` — ~0.5 MB (структура сертификатов, live/archive).
- `/root/.secrets/certbot` и `/etc/letsencrypt/renewal-hooks/deploy/` — секреты и deploy-hookи.
Эти размеры небольшие сейчас, но могут расти за счёт логов и числа доменов — учитывать при выборе стратегии бэкапа.
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домены, схема сети.
- [Выпуск сертификата Let's Encrypt (DNS-01)](../network/ssl-letsencrypt-dns01.md) — certbot, Beget API, интеграция с NPM.
- [Роутер Netcraze Speedster](../network/router-netcraze-speedster.md) — VPN и telnet, используемые vpn-route-check.

View File

@@ -0,0 +1,164 @@
# Контейнер 101 (nextcloud): Nextcloud, PostgreSQL, Redis
Подробное описание LXC-контейнера **101** на Proxmox (192.168.1.101): облачное хранилище Nextcloud за NPM (https://cloud.katykhin.ru), PostgreSQL 16, Redis для кэша и блокировок, внешнее хранилище «Игры».
---
## Общие сведения
- **Хостнейм:** nextcloud
- **IP:** 192.168.1.101/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 2 core, 3 GB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 101 -- bash` или по SSH на 192.168.1.101, если настроен.
Диск контейнера: ~10 GB, занято ~3.8 GB. Основной объём данных — в смонтированных каталогах хоста: `/mnt/nextcloud-data/` (приложение + БД) и `/mnt/nextcloud-extra/` (внешнее хранилище «Игры», порядка нескольких TB). Следить за местом на корне и за логами (см. раздел «Логи» и TODO).
---
## Доступ и логины
- **Debian (CT 101):** логин `root` (пароль — в менеджере паролей или как настраивал при установке).
- **Nextcloud (веб):** https://cloud.katykhin.ru (через NPM). Логины пользователей — учётные записи Nextcloud (в т.ч. админ); пароли в менеджере паролей или задаются при первом входе.
---
## Сервисы (Docker Compose)
Один проект: `/opt/nextcloud/docker-compose.yml`. Сеть: **nextcloud_default** (bridge).
| Сервис | Образ | Порты (хост) | Назначение |
|-----------|--------------------|--------------|------------|
| nextcloud | nextcloud:latest | 8080→80 | Nextcloud (Apache), доступ по https://cloud.katykhin.ru через NPM |
| db | postgres:16 | — | PostgreSQL 16, БД nextcloud |
| redis | redis:7-alpine | — | Redis (кэш, блокировки), appendonly |
---
## 1. Nextcloud
**Образ:** `nextcloud:latest` (на момент проверки — Nextcloud 32.0.6).
**Порты:** 8080 (хост) → 80 (контейнер). Снаружи доступ только через NPM: https://cloud.katykhin.ru → proxy на 192.168.1.101:8080.
**Тома:**
- `/mnt/nextcloud-data/html``/var/www/html` (код, `config/`, `data/`, приложения).
- `/mnt/nextcloud-extra``/mnt/nextcloud-extra` (внутри контейнера; используется для внешнего хранилища «Игры»).
- `/opt/nextcloud/php-uploads.ini``/usr/local/etc/php/conf.d/zz-uploads.ini` (лимиты загрузки).
**Переменные окружения (compose):**
- `NEXTCLOUD_TRUSTED_DOMAINS`: cloud.katykhin.ru 192.168.1.101
- `OVERWRITEPROTOCOL`, `OVERWRITEHOST`, `OVERWRITECLIURL`: https и cloud.katykhin.ru
- `REDIS_HOST`: redis
- `POSTGRES_*`: хост db, БД nextcloud, пользователь и пароль БД (в compose заданы `nextcloud` / `nextcloud`; в `config.php` приложения может быть другой пользователь БД, заданный при установке).
**Конфиг приложения:** `/var/www/html/config/config.php` (внутри контейнера; на хосте путь — `/mnt/nextcloud-data/html/config/config.php`). В нём: trusted_domains, overwrite*, redis, datadirectory (`/var/www/html/data`), dbtype pgsql, dbhost/dbname/dbuser/dbpassword, instanceid, passwordsalt, secret и др. Редактировать при необходимости через `occ config:system:set` или правку файла с последующим перезапуском контейнера.
**PHP (загрузки):** `/opt/nextcloud/php-uploads.ini` на хосте:
- `upload_max_filesize = 64G`, `post_max_size = 64G`
- `memory_limit = 2G`, `max_execution_time = 7200`, `max_input_time = 7200`
- `upload_max_chunk_size` задаётся в config.php (67108864).
**Внешнее хранилище:** В Nextcloud настроено локальное внешнее хранилище «Игры» (Local): точка монтирования в интерфейсе — «/Игры», каталог на диске — `/mnt/nextcloud-extra/games`. Данные лежат на хосте в `/mnt/nextcloud-extra/` (в т.ч. каталог `games`); объём порядка нескольких TB.
**Команды:**
```bash
docker exec nextcloud-nextcloud-1 php /var/www/html/occ status
docker exec nextcloud-nextcloud-1 php /var/www/html/occ config:list system
docker exec nextcloud-nextcloud-1 php /var/www/html/occ files_external:list
docker logs nextcloud-nextcloud-1
docker restart nextcloud-nextcloud-1
```
Обновление приложения (если нужно): через `occ upgrade` или официальную инструкцию Nextcloud; перед этим — бэкап данных и БД.
---
## 2. PostgreSQL (db)
**Образ:** postgres:16.
**Том:** `/mnt/nextcloud-data/pgdata``/var/lib/postgresql/data`.
**Переменные:** `POSTGRES_DB=nextcloud`, `POSTGRES_USER=nextcloud`, `POSTGRES_PASSWORD=nextcloud` (в compose; приложение может подключаться под другим пользователем из config.php).
**Healthcheck:** `pg_isready -U nextcloud`.
Подключение к БД с хоста CT 101 (для администрирования):
```bash
docker exec -it nextcloud-db-1 psql -U nextcloud -d nextcloud
```
---
## 3. Redis
**Образ:** redis:7-alpine.
**Команда:** `redis-server --appendonly yes`.
**Том:** анонимный Docker volume (данные Redis в `/var/lib/docker/volumes/...` на хосте CT 101). Используется Nextcloud для memcache.distributed и memcache.locking; пароль не задан (доступ только внутри сети контейнеров).
---
## Порты
| Порт | Сервис | Примечание |
|------|----------|------------|
| 8080 | Nextcloud| HTTP внутри LAN; снаружи доступ через NPM (HTTPS cloud.katykhin.ru). |
PostgreSQL и Redis не проброшены на хост — доступ только из сети nextcloud_default.
---
## Логи и ротация
- **Nextcloud:** основной лог приложения — `/var/www/html/data/nextcloud.log` (в контейнере; на хосте — `/mnt/nextcloud-data/html/data/nextcloud.log`). На момент проверки файл уже порядка **сотен MB**. Встроенной ротации по размеру/времени в Nextcloud нет; в контейнере и на хосте **logrotate для этого файла не настроен** — риск разрастания и заполнения раздела (см. TODO).
- **PostgreSQL:** логи по умолчанию в stdout (видны через `docker logs nextcloud-db-1`). Отдельного файлового лога и logrotate не проверялось.
- **Docker:** вывод контейнеров — `docker logs`. Ротация логов Docker (json-file) зависит от настроек демона; при необходимости задать max-size/max-file в `/etc/docker/daemon.json`.
Рекомендуется добавить правило logrotate для `nextcloud.log` (по размеру или по дням) и при необходимости ограничить уровень логирования в Nextcloud.
---
## Запуск и обновление
Рабочий каталог: `/opt/nextcloud/`.
```bash
cd /opt/nextcloud
docker compose up -d
docker compose ps
docker compose logs -f nextcloud
```
Перед обновлением образов — сделать бэкап БД и каталога данных:
- БД: `docker exec nextcloud-db-1 pg_dump -U nextcloud nextcloud`
- Данные: `/mnt/nextcloud-data/html` (в т.ч. `config/`, `data/`), при необходимости `/mnt/nextcloud-extra`.
---
## Уязвимости и риски
1. **Пароли в compose:** В `docker-compose.yml` заданы `POSTGRES_PASSWORD: nextcloud` и те же учётные данные в блоке nextcloud. Файл лежит на сервере; не коммитить в публичный репозиторий. При необходимости вынести секреты в `.env`.
2. **Пароль БД в config.php:** В `config/config.php` хранится пароль подключения к PostgreSQL (и другие секреты). Права на файл должны ограничивать чтение (владелец www-data, режим 640 или строже).
3. **Nextcloud доступ по 8080:** Порт 8080 открыт на 0.0.0.0 внутри CT 101. Доступ из интернета только через NPM (HTTPS). Убедиться, что на роутере/фаерволе не пробрасывается 8080 на 192.168.1.101.
4. **Redis без пароля:** Приемлемо, так как Redis не проброшен наружу и доступен только контейнерам в одной сети. При добавлении других стеков в тот же Docker-сеть — учитывать, что Redis доступен без аутентификации.
5. **Логи:** Отсутствие ротации для `nextcloud.log` может привести к заполнению диска (см. TODO).
6. **Квота и внешнее хранилище «Игры»:** после переноса данных с SSD на HDD и смены пути внешнего хранилища (`/mnt/nextcloud-extra/games`) в БД могли остаться старые записи `storage` и кэша (oc_storages/oc_filecache) для прежнего пути. Это приводит к завышенному «Использовано» и постоянному статусу «Ожидается» у «Игры». При будущих переносах хранилища важно очищать устаревшие storages и запускать пересканирование (occ files:scan и files_external:scan), чтобы квота считалась корректно.
---
## TODO по контейнеру 101
- [ ] **Ротация nextcloud.log:** Настроить logrotate для `/mnt/nextcloud-data/html/data/nextcloud.log` (или пути на хосте CT 101): ротация по размеру (например 100200 MB) или по дням, сжатие, ограничение числа копий. Либо включить в Nextcloud логирование в syslog и ротировать его.
- [ ] **Уровень логирования:** В Nextcloud при необходимости снизить уровень лога (loglevel) в config.php или через `occ config:system:set loglevel --value 1` (1 = только ошибки), чтобы уменьшить рост лога.
- [ ] **Резервное копирование:** Регулярный бэкап:
- дамп PostgreSQL (данные в `/mnt/nextcloud-data/pgdata`, сейчас ~2.3 GB);
- каталог `/mnt/nextcloud-data/html` (код, `config/`, `data/` — сейчас ~2.3 GB);
- при необходимости внешнее хранилище `/mnt/nextcloud-extra` (в т.ч. `games` — сейчас ~5.9 TB).
Проверить, что бэкап включает конфиг и что восстановление из дампа и данных проверено.
- [ ] **Мониторинг диска:** Следить за занятостью корня контейнера и раздела, на котором лежат `/mnt/nextcloud-data` и `/mnt/nextcloud-extra`. При необходимости — алерты при достижении порога (например 85%).
- [ ] **Trusted domains:** В config.php на момент проверки указан только `cloud.katykhin.ru`. В compose задан также `192.168.1.101` — при необходимости доступа по IP добавить его в trusted_domains через `occ config:system:set trusted_domains 1 --value 192.168.1.101` (индексы по необходимости скорректировать).
- [ ] **Cron Nextcloud:** Убедиться, что фоновые задачи выполняются (режим cron или AJAX). Проверить: `docker exec nextcloud-nextcloud-1 php /var/www/html/occ background:job:list` или настройки в разделе «Основные» веб-интерфейса. При использовании cron на хосте — добавить задачу вида `*/5 * * * * docker exec nextcloud-nextcloud-1 php /var/www/html/cron.php`.
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домен cloud.katykhin.ru, NPM.
- [Контейнер 100](container-100.md) — NPM, через который открыт доступ к Nextcloud по HTTPS.

View File

@@ -0,0 +1,208 @@
# Контейнер 103 (Gitea): Gitea, PostgreSQL, act_runner, CouchDB (Obsidian)
Подробное описание LXC-контейнера **103** на Proxmox (192.168.1.103): Git-сервер Gitea с Actions (runner), база PostgreSQL, CouchDB для синхронизации Obsidian (домен obsidian.katykhin.ru).
---
## Общие сведения
- **Хостнейм:** gitea
- **IP:** 192.168.1.103/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 1 core, 2 GB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 103 -- bash` или `ssh` на 192.168.1.103, если настроен.
Диск контейнера: 15 GB, занято ~2.6 GB. Основной объём — данные Docker (образы, тома Gitea, PostgreSQL, CouchDB). Следить за местом и логами (см. раздел «Логи и ротация» и TODO).
---
## Доступ и логины
- **Debian (CT 103):** логин `root` (пароль — в менеджере паролей или как настраивал при установке).
- **Gitea (веб):** http://192.168.1.103:3000 (или через NPM по домену git.katykhin.ru, если настроен). Учётные записи — пользователи Gitea. Репозитории могут иметь origin на Gitea; при необходимости пуш в GitHub — отдельный remote (например `github`), команда вида `git push github main`.
- **CouchDB (Obsidian sync):** http://192.168.1.103:5984. Админ (пользователь **obsidian**) и пароль заданы в `/opt/docker/couchdb/local.d/local.ini` (секция `[admins]`); клиент Obsidian подключается по URL и своим учётным данным.
---
## Сервисы (Docker)
Два независимых набора сервисов:
1. **Gitea (compose)** — в `/opt/gitea/`: Gitea, PostgreSQL, act_runner. Сеть **gitea_default**.
2. **CouchDB** — запущен отдельным контейнером (без compose в репозитории), данные в `/opt/docker/couchdb/`.
| Контейнер | Образ | Порты (хост) | Назначение |
|-----------------|--------------------------|------------------|------------|
| gitea | gitea:1.25 | 3000, 2222 | Git-сервер, веб, SSH для Git |
| gitea-db-1 | postgres:16-alpine | — | БД Gitea |
| gitea-runner-1 | gitea/act_runner:latest | — | Gitea Actions (CI) |
| couchdb | couchdb:3 | 5984 | Бэкенд синхронизации Obsidian (obsidian.katykhin.ru) |
---
## 1. Gitea (сервер)
**Каталог:** `/opt/gitea/`
**Compose:** `docker-compose.yml`. Запуск: `cd /opt/gitea && docker compose up -d`.
**Порты:** 3000 (HTTP), 2222 (SSH для git clone по SSH).
**Тома:**
- `gitea-data` (volume) → `/data` (внутри: `git/repositories`, `gitea/` — конфиг, логи, сессии, аватары, вложения, indexers, LFS, Actions logs/artifacts).
- `gitea-postgres` → данные PostgreSQL.
- `runner-data` → данные act_runner.
**Переменные окружения (compose):**
- База: `GITEA__database__*` (postgres, db:5432, user/passwd `gitea`).
- Сервер: `GITEA__server__DOMAIN`, `ROOT_URL` = 192.168.1.103:3000, `SSH_PORT` = 2222.
- Runner: `GITEA_RUNNER_REGISTRATION_TOKEN` из файла `.env` (не коммитить).
**Конфиг приложения:** внутри тома `gitea-data`, путь в контейнере `/data/gitea/conf/app.ini`. На хосте: `/var/lib/docker/volumes/gitea_gitea-data/_data/gitea/conf/app.ini`.
В нём: репозитории в `/data/git/repositories`, БД postgres (db:5432), LFS, сессии (file), логи в `/data/gitea/log`, `MODE = console` (логи в stdout → Docker). OFFLINE_MODE = true. INTERNAL_TOKEN и LFS_JWT_SECRET заданы в app.ini.
**Команды:**
```bash
cd /opt/gitea && docker compose up -d
docker logs gitea
docker exec gitea ls -la /data/gitea/conf
```
---
## 2. PostgreSQL (Gitea)
**Образ:** postgres:16-alpine.
**Том:** `gitea-postgres``/var/lib/postgresql/data`.
**Переменные:** POSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DB = gitea (заданы в compose).
Healthcheck: pg_isready. Зависимость: Gitea ждёт здоровой БД.
**Команды:**
```bash
docker exec gitea-db-1 pg_isready -U gitea
docker exec gitea-db-1 psql -U gitea -d gitea -c '\\dt'
```
---
## 3. Gitea act_runner (Actions)
**Образ:** gitea/act_runner:latest.
**Тома:** `runner-data``/data`; `/var/run/docker.sock` → сокет Docker (для запуска job-контейнеров).
**Переменные:** GITEA_INSTANCE_URL=http://server:3000, GITEA_RUNNER_REGISTRATION_TOKEN из `.env`, GITEA_RUNNER_NAME=gitea-103-runner, GITEA_RUNNER_LABELS=docker:docker://alpine:latest.
Регистрация runner выполняется при первом запуске по токену из Gitea (Администрирование → Actions → Runners). Токен хранится в `/opt/gitea/.env`.
**Команды:**
```bash
docker logs gitea-runner-1
docker restart gitea-runner-1
```
---
## 4. CouchDB (Obsidian sync)
**Образ:** couchdb:3.
**Порты:** 5984 (хост) → 5984 (контейнер).
**Тома (binds):**
- `/opt/docker/couchdb/data``/opt/couchdb/data`
- `/opt/docker/couchdb/local.d``/opt/couchdb/etc/local.d`
Контейнер запущен вручную (не из compose в `/opt/gitea`), политика перезапуска `unless-stopped`. После перезагрузки CT Docker поднимает контейнер автоматически.
**Конфигурация на хосте:**
- `/opt/docker/couchdb/local.d/docker.ini` — базовая секция [couchdb], uuid.
- `/opt/docker/couchdb/local.d/local.ini` — [httpd] enable_cors; [cors] origins=*, credentials, methods, headers; [admins] — пользователь (имя **obsidian**) и хэш пароля (pbkdf2). Пароль админа CouchDB хранится в этом файле; не коммитить и не светить в документации.
**Смена пароля CouchDB:** через API CouchDB (PUT /_node/_local/_config/admins/obsidian) или пересоздание контейнера с новыми переменными/конфигом. После смены — `docker restart couchdb`.
**CORS:** сейчас origins=* — приемлемо в пределах домашней сети. При выводе доступа через NPM (obsidian.katykhin.ru) можно ограничить origins до конкретного домена.
**Данные:** БД Obsidian (vault) в `/opt/docker/couchdb/data` (шарды, _dbs.couch, _nodes.couch). Размер порядка десятков MB.
**Доступ:** Снаружи — http://192.168.1.103:5984. Через NPM: obsidian.katykhin.ru → proxy на 192.168.1.103:5984 (если настроен). Клиент Obsidian Sync подключается к CouchDB по URL и своим учётным данным.
**Команды:**
```bash
docker logs couchdb
docker restart couchdb
curl -s http://192.168.1.103:5984/
```
**Рекомендация:** Оформить запуск CouchDB в отдельный `docker-compose.yml` в `/opt/docker/couchdb/` для воспроизводимости и документирования (см. TODO).
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|-------|----------------------------|
| 3000 | Gitea (веб) |
| 2222 | Gitea (SSH для git) |
| 5984 | CouchDB (Obsidian sync) |
---
## Логи и ротация
- **Gitea:** в app.ini задано `MODE = console`, `ROOT_PATH = /data/gitea/log`. Логи идут в stdout и попадают в драйвер Docker **json-file** без ограничения размера и количества файлов — со временем каталог `/var/lib/docker/containers/<id>/*.log` может разрастаться (см. TODO).
- **PostgreSQL:** логи в stdout контейнера, то же хранилище Docker.
- **act_runner:** логи в stdout.
- **CouchDB:** логи в stdout.
**Системный logrotate** в CT затрагивает только стандартные сервисы (apt, dpkg, btmp, wtmp и т.д.). Отдельных правил для Docker или Gitea нет. Ротация логов контейнеров не настроена — задаётся через `docker-compose` (logging driver options: max-size, max-file) или через `/etc/docker/daemon.json` (default).
**Риск:** при активном использовании Gitea и Actions логи контейнеров могут заполнить диск. Нужно включить ограничение размера логов Docker (см. TODO).
---
## Запуск и порядок поднятия
1. **Gitea (compose):**
`cd /opt/gitea && docker compose up -d`
Порядок: db → server (healthcheck) → runner.
2. **CouchDB:** уже запущен отдельным контейнером. Если после перезагрузки контейнер не поднялся:
```bash
docker run -d --name couchdb --restart unless-stopped \
-p 5984:5984 \
-v /opt/docker/couchdb/data:/opt/couchdb/data \
-v /opt/docker/couchdb/local.d:/opt/couchdb/etc/local.d \
couchdb:3
```
(Параметры приведены по текущему inspect; предпочтительно перейти на compose в `/opt/docker/couchdb/`.)
После смены конфига Gitea (app.ini): перезапуск контейнера — `docker restart gitea`. После смены пароля/пользователя в CouchDB local.ini — `docker restart couchdb`.
---
## Уязвимости и риски
1. **Пароли в конфигах:** В `docker-compose.yml` (Gitea) заданы пароль БД и креды Gitea (gitea/gitea). Файл лежит только на сервере; не помещать в публичный репозиторий. То же для `/opt/gitea/.env` (GITEA_RUNNER_REGISTRATION_TOKEN).
2. **Пароль админа CouchDB** хранится в `/opt/docker/couchdb/local.d/local.ini` (секция [admins]). Ограничить права на каталог (например chmod 700 local.d, владелец root).
3. **Gitea и CouchDB по IP:** Доступ по 192.168.1.103:3000 и :5984 из LAN. Если нужен доступ снаружи — только через NPM (HTTPS, домены git.katykhin.ru, obsidian.katykhin.ru) и не пробрасывать порты 3000/5984 напрямую в интернет.
4. **Логи Docker:** Ротация не настроена — возможен рост логов и заполнение диска (см. TODO).
5. **CouchDB CORS:** В конфиге включены CORS с origins = * и credentials = true. Достаточно для Obsidian; при расширении использования оценить ограничение origins.
---
## TODO по контейнеру 103
- [ ] **Логи Docker:** Включить ограничение размера логов для контейнеров: в `docker-compose.yml` (Gitea) добавить для сервисов `logging: driver: json-file options: max-size: "50m" max-file: "3"` или задать default в `/etc/docker/daemon.json` и перезапустить Docker. После этого перезапустить контейнеры.
- [ ] **CouchDB compose:** Создать `/opt/docker/couchdb/docker-compose.yml` с текущими томами и портами, перейти на `docker compose up -d` вместо ручного `docker run`, зафиксировать в документации.
- [ ] **Домены и NPM:** При необходимости настроить в NPM proxy для git.katykhin.ru → 192.168.1.103:3000 и obsidian.katykhin.ru → 192.168.1.103:5984, выпустить SSL (certbot + deploy в NPM). В Gitea при использовании домена обновить ROOT_URL и DOMAIN в compose/app.ini.
- [ ] **Мониторинг диска:** Следить за местом на корне (df -h). При желании — оповещение при заполнении выше порога (например 80%).
- [ ] **Резервное копирование:** Регулярный бэкап критичных данных (оценка размеров на момент документации):
- **`/var/lib/docker/volumes/gitea_gitea-data`** — репозитории, конфиг Gitea, логи, сессии, вложения, LFS, Actions (артефакты/логи). Размер: git ~25 MB, gitea (всё остальное) ~сотни MB в зависимости от репо и логов. Бэкапить весь volume или минимум `_data/git`, `_data/gitea/conf`, `_data/gitea/sessions`, при необходимости `_data/gitea/attachments`, `_data/gitea/actions_*`.
- **`/var/lib/docker/volumes/gitea_gitea-postgres`** — БД Gitea. Размер ~71 MB. Для консистентного бэкапа — дамп через `pg_dump` (см. ниже).
- **`/var/lib/docker/volumes/gitea_runner-data`** — данные runner (~8 KB). По желанию.
- **`/opt/gitea`** — docker-compose.yml, .env (секреты). ~12 KB. Обязательно; .env не коммитить.
- **`/opt/docker/couchdb/data`** — данные CouchDB (Obsidian). ~56 MB.
- **`/opt/docker/couchdb/local.d`** — конфиги CouchDB (в т.ч. admins). ~12 KB. Обязательно; не светить в открытом доступе.
Рекомендуемый способ для PostgreSQL: `docker exec gitea-db-1 pg_dump -U gitea gitea > backup_gitea_$(date +%Y%m%d).sql` и сохранять дамп вне контейнера. Для Gitea data — копирование тома или `tar` по каталогам с остановкой записи (при возможности кратко приостановить Gitea или делать бэкап в момент минимальной активности).
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домены (в т.ч. obsidian.katykhin.ru), схема сети.
- [Контейнер 100 (nginx)](container-100.md) — NPM, через который при необходимости проксируются git.katykhin.ru и obsidian.katykhin.ru.

View File

@@ -0,0 +1,158 @@
# Контейнер 104 (Paperless): Paperless-ngx, PostgreSQL, Redis
Подробное описание LXC-контейнера **104** на Proxmox (192.168.1.104): архив документов Paperless-ngx (домен docs.katykhin.ru), PostgreSQL 18, Redis 8 для очередей задач.
---
## Общие сведения
- **Хостнейм:** paperless
- **IP:** 192.168.1.104/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 1 core, 2 GB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 104 -- bash` или по SSH на 192.168.1.104, если настроен.
Диск контейнера: ~10 GB, занято ~3.9 GB. Основной объём данных — в каталоге **/mnt/paperless-data/** (ZFS: `tank/subvol-104-disk-0`): данные приложения, медиа (документы), БД PostgreSQL. Плюс образы и тома Docker (~2 GB). Следить за местом и логами (см. раздел «Логи и ротация» и TODO).
---
## Доступ и логины
- **Debian (CT 104):** логин `root` (пароль — в менеджере паролей или как настраивал при установке).
- **Paperless (веб):** http://192.168.1.104:8000 (или через NPM: https://docs.katykhin.ru, если настроен). Учётные записи — пользователи Paperless (создаются в веб-интерфейсе).
---
## Сервисы (Docker Compose)
Один проект: **/opt/paperless/docker-compose.yml**. Сеть: **paperless_default** (bridge).
| Контейнер | Образ | Порты (хост) | Назначение |
|--------------------------|--------------------------|--------------|------------|
| paperless-webserver-1 | paperless-ngx/paperless-ngx:latest | 8000 | Веб-интерфейс, API, OCR, фоновые задачи (Celery) |
| paperless-db-1 | postgres:18 | — | БД Paperless |
| paperless-broker-1 | redis:8 | — | Очередь задач (Celery broker) |
---
## 1. Paperless-ngx (webserver)
**Каталог:** `/opt/paperless/`
**Compose:** `docker-compose.yml`, переменные из **docker-compose.env** (не коммитить).
**Порты:** 8000 (хост) → 8000 (контейнер).
**Тома:**
- `/mnt/paperless-data/data``/usr/src/paperless/data` (конфиг, индекс, логи, celerybeat-schedule, lock-файлы).
- `/mnt/paperless-data/media``/usr/src/paperless/media` (оригиналы и производные документов: `documents/`).
- `./export``/usr/src/paperless/export` (экспорт из приложения).
- `./consume``/usr/src/paperless/consume` (каталог для автоматического импорта: сюда класть файлы для постановки в очередь).
**Переменные окружения:** из `docker-compose.env`: PAPERLESS_URL, PAPERLESS_SECRET_KEY, PAPERLESS_TIME_ZONE, PAPERLESS_OCR_LANGUAGE(S). В compose заданы: PAPERLESS_REDIS=redis://broker:6379, PAPERLESS_DBHOST=db.
**Структура данных на хосте:**
- `/mnt/paperless-data/data/``index/` (поисковый индекс), `log/` (celery.log, paperless.log; приложение может создавать rotated файлы celery.log.1, .2 и т.д.), `celerybeat-schedule.db`, `.index_version`, `migration_lock`.
- `/mnt/paperless-data/media/documents/` — подкаталоги с оригинальными и обработанными файлами документов.
**Команды:**
```bash
cd /opt/paperless && docker compose up -d
docker logs paperless-webserver-1
docker exec paperless-webserver-1 document_exporter /usr/src/paperless/export --no-input # экспорт
```
Импорт: положить файлы (PDF, изображения и т.д.) в `/opt/paperless/consume/` на хосте — Paperless подхватит их и обработает (OCR, теги, корреспонденты настраиваются в веб-интерфейсе).
---
## 2. PostgreSQL (db)
**Образ:** postgres:18.
**Том:** `/mnt/paperless-data/pgdata``/var/lib/postgresql`.
**Переменные:** POSTGRES_DB=paperless, POSTGRES_USER=paperless, POSTGRES_PASSWORD=paperless (в compose).
Зависимость: webserver зависит от db и broker.
**Команды:**
```bash
docker exec paperless-db-1 pg_isready -U paperless
docker exec paperless-db-1 psql -U paperless -d paperless -c '\dt'
```
---
## 3. Redis (broker)
**Образ:** redis:8.
**Том:** volume `redisdata``/data` (внутри контейнера). На хосте: `/var/lib/docker/volumes/paperless_redisdata/_data`.
Используется как брокер для Celery (очередь задач OCR и др.).
**Команды:**
```bash
docker exec paperless-broker-1 redis-cli ping
docker logs paperless-broker-1
```
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|------|----------------------|
| 8000 | Paperless-ngx (веб) |
---
## Логи и ротация
- **Paperless:** логи приложения в **/mnt/paperless-data/data/log/**:
- `celery.log` — фоновые задачи (OCR, индекс и т.д.); приложение может делать собственную ротацию (celery.log.1, .2, .3). На момент проверки каталог ~568 KB.
- `paperless.log` — основной лог приложения.
Для этих файлов **нет правил logrotate** на хосте — при длительной работе объём может расти (см. TODO).
- **Docker:** драйвер логов контейнеров — **json-file** без ограничения размера и количества файлов. Рост логов контейнеров (stdout/stderr) может заполнять диск.
**Системный logrotate** в CT — только стандартные правила (apt, dpkg, btmp, wtmp). Отдельных правил для Paperless или Docker нет.
**Риск:** при большом количестве документов и активной очереди Celery логи в `data/log/` и логи Docker могут разрастаться. Рекомендуется настроить ротацию (см. TODO).
---
## Запуск и порядок поднятия
1. Убедиться, что смонтирован `/mnt/paperless-data` (ZFS или иной бэкенд).
2. `cd /opt/paperless && docker compose up -d`.
Порядок: broker и db поднимаются первыми, затем webserver (depends_on).
После смены переменных в `docker-compose.env` или compose: `docker compose up -d` (пересоздание при необходимости). Обновление образа: `docker compose pull && docker compose up -d`.
---
## Уязвимости и риски
1. **Пароли в конфигах:** В `docker-compose.yml` заданы пароль БД (paperless/paperless). В `docker-compose.env` — PAPERLESS_SECRET_KEY, PAPERLESS_URL и др. Файлы лежат только на сервере; не помещать в публичный репозиторий. Ограничить права на `docker-compose.env` (например chmod 600).
2. **Доступ по порту 8000:** Веб-интерфейс доступен по 192.168.1.104:8000 из LAN. Снаружи доступ только через NPM (https://docs.katykhin.ru). Не пробрасывать 8000 в интернет.
3. **Логи:** Ротация логов Paperless (`data/log/`) и Docker не настроена — возможен рост и заполнение диска (см. TODO).
4. **Каталог consume:** Файлы в `/opt/paperless/consume/` автоматически обрабатываются и удаляются после импорта. Не класть туда единственные копии важных файлов без бэкапа.
---
## TODO по контейнеру 104
- [ ] **Логи Paperless:** Настроить logrotate для `/mnt/paperless-data/data/log/*.log`: например еженедельная ротация или по размеру (max 50100 MB), хранить 34 копии, сжатие. Создать `/etc/logrotate.d/paperless` и проверить работу.
- [ ] **Логи Docker:** Включить ограничение размера логов контейнеров: в `docker-compose.yml` добавить для сервисов `logging: driver: json-file options: max-size: "50m" max-file: "3"` или задать default в `/etc/docker/daemon.json` и перезапустить Docker, затем контейнеры.
- [ ] **Домен и NPM:** При необходимости настроить в NPM proxy для docs.katykhin.ru → 192.168.1.104:8000, выпустить SSL. В Paperless в `docker-compose.env` задать PAPERLESS_URL=https://docs.katykhin.ru (если ещё не задан).
- [ ] **Мониторинг диска:** Следить за местом на корне и на `/mnt/paperless-data` (df -h). При желании — оповещение при заполнении выше порога (например 80%).
- [ ] **Резервное копирование:** Регулярный бэкап критичных данных (оценка размеров на момент документации):
- **`/mnt/paperless-data/data`** — конфиг, индекс, логи, celerybeat-schedule. ~1 MB (логи могут расти).
- **`/mnt/paperless-data/media`** — все документы (оригиналы и производные). ~178 MB (будет расти с новыми документами).
- **`/mnt/paperless-data/pgdata`** — БД PostgreSQL. ~22 MB. Для консистентного бэкапа предпочтительно дамп: `docker exec paperless-db-1 pg_dump -U paperless paperless > backup_paperless_$(date +%Y%m%d).sql`.
- **`/var/lib/docker/volumes/paperless_redisdata`** — данные Redis. ~12 KB. Восстановление не критично (очередь задач), по желанию.
- **`/opt/paperless`** — docker-compose.yml, docker-compose.env (секреты), каталоги consume/export. ~20 KB. Обязательно; docker-compose.env не коммитить.
Учитывать, что `/mnt/paperless-data` может быть отдельным ZFS-томом (tank/subvol-104-disk-0) — при бэкапе с хоста Proxmox нужно включить этот каталог или снапшот ZFS.
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домен docs.katykhin.ru, схема сети.
- [Контейнер 100 (nginx)](container-100.md) — NPM, через который проксируется docs.katykhin.ru.
- [Paperless + Ollama: поиск по документам](paperless-ollama.md) — интеграция Paperless-ngx с Ollama для вопросов по документам.

View File

@@ -0,0 +1,127 @@
# Контейнер 105 (RAG-service): RAG API (mini-lm)
Подробное описание LXC-контейнера **105** на Proxmox (192.168.1.105): сервис RAG (Retrieval-Augmented Generation) на базе sentence-transformers, API для семантического поиска и эмбеддингов. Домен: mini-lm.katykhin.ru.
---
## Общие сведения
- **Хостнейм:** rag-service
- **IP:** 192.168.1.105/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 1 core, 1 GB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 105 -- bash` или по SSH на 192.168.1.105, если настроен.
Диск контейнера: ~10 GB, занято **~6.8 GB (74%)**. Основной объём: образ Docker (~4.1 GB), build cache (~2.4 GB, можно освободить `docker builder prune`), данные приложения в `/home/rag-service/data/` (модели ~734 MB, векторы ~2 MB). Следить за местом: при нехватке — почистить build cache и/или ограничить логи Docker (см. TODO).
---
## Доступ и логины
- **Debian (CT 105):** логин `root` (пароль — в менеджере паролей или как настраивал при установке).
- **RAG API:** http://192.168.1.105:8000 (или через NPM: https://mini-lm.katykhin.ru). Авторизация по заголовку **X-API-Key**; ключ задаётся в `.env` (RAG_API_KEY). При RAG_ALLOW_NO_AUTH=true запросы без ключа допускаются (не рекомендуется снаружи).
---
## Сервисы (Docker Compose)
Один проект: **/home/rag-service/docker-compose.yml**. Образ собирается локально из **Dockerfile** в том же каталоге. Сеть: **rag-service_default** (bridge).
| Контейнер | Образ | Порты (хост) | Назначение |
|-------------|--------------------------|--------------|------------|
| rag-service | rag-service-rag-service (build) | 8000 | FastAPI: эмбеддинги, поиск по векторам, health |
---
## 1. RAG-service (приложение)
**Каталог:** `/home/rag-service/`
**Compose:** `docker-compose.yml`, переменные из **.env** (не коммитить). Образ: `build: context: ., dockerfile: Dockerfile`.
**Порты:** 8000 (хост) → 8000 (контейнер).
**Тома:**
- `./data/models``/app/data/models` (кэш моделей sentence-transformers: all-MiniLM-L12-v2, rubert-base-cased и др.).
- `./data/vectors``/app/data/vectors` (файл векторов, например `vectors.npz`; автосохранение по RAG_AUTOSAVE_INTERVAL).
**Переменные окружения (из .env и compose):**
- Модель: RAG_MODEL (по умолчанию sentence-transformers/all-MiniLM-L12-v2), RAG_CACHE_DIR=/app/data/models.
- Векторы: RAG_VECTORS_PATH=/app/data/vectors/vectors.npz, RAG_MAX_EXAMPLES, RAG_SCORE_MULTIPLIER, RAG_BATCH_SIZE, RAG_MIN_TEXT_LENGTH.
- API: RAG_API_HOST=0.0.0.0, RAG_API_PORT=8000.
- Безопасность: **RAG_API_KEY** (обязателен для продакшена), RAG_ALLOW_NO_AUTH (по умолчанию false).
- Автосохранение: RAG_AUTOSAVE_INTERVAL (секунды).
- Логи: LOG_LEVEL (по умолчанию INFO).
**Healthcheck:** GET /api/v1/health с заголовком X-API-Key (если RAG_API_KEY задан). interval 30s, start_period 60s.
**Структура на хосте:**
- `/home/rag-service/data/models/` — подкаталоги вида `models--sentence-transformers--all-MiniLM-L12-v2`, `models--DeepPavlov--rubert-base-cased` (скачанные модели). ~734 MB.
- `/home/rag-service/data/vectors/` — vectors.npz и др. ~2 MB.
- `/home/rag-service/.env` — секреты и настройки. Обязательно бэкапить отдельно, не коммитить.
- Исходный код приложения (app/, Dockerfile, pyproject.toml и т.д.) — в том же homedir; при пересборке образа используется этот контекст.
**Команды:**
```bash
cd /home/rag-service && docker compose up -d
docker logs rag-service
docker compose build --no-cache # пересборка после изменений кода
curl -s -H "X-API-Key: <key>" http://192.168.1.105:8000/api/v1/health
```
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|------|---------------------|
| 8000 | RAG API (веб, API) |
---
## Логи и ротация
- **RAG-service:** логи приложения идут в **stdout** контейнера (LOG_LEVEL из .env) и попадают в драйвер Docker **json-file** без ограничения размера и количества файлов.
- **Системный logrotate** в CT — только стандартные правила (apt, dpkg, btmp, wtmp). Отдельных правил для RAG или Docker нет.
**Риск:** при активной работе логи контейнера могут разрастаться и вместе с образом и build cache заполнить диск (уже 74%). Рекомендуется включить ограничение логов Docker и следить за местом (см. TODO).
---
## Запуск и порядок поднятия
1. Зануться в каталог: `cd /home/rag-service`.
2. При первом запуске или после изменений кода: `docker compose build` (при необходимости `docker compose up -d --build`).
3. Запуск: `docker compose up -d`.
После смены переменных в `.env`: `docker compose up -d` (пересоздание контейнера при необходимости). После смены кода или Dockerfile: `docker compose build && docker compose up -d`.
---
## Уязвимости и риски
1. **Секреты в .env:** RAG_API_KEY и прочие переменные хранятся в `/home/rag-service/.env`. Файл не должен попадать в публичный репозиторий. Ограничить права (chmod 600) и владельца.
2. **Доступ по порту 8000:** API доступен по 192.168.1.105:8000 из LAN. Снаружи доступ только через NPM (https://mini-lm.katykhin.ru). Не пробрасывать 8000 в интернет без защиты (API key обязателен при RAG_ALLOW_NO_AUTH=false).
3. **Логи Docker:** Ротация не настроена — возможен рост логов и заполнение диска (см. TODO).
4. **Мало места на диске (74%):** Образ ~4 GB, build cache ~2.4 GB. При нехватке места: `docker builder prune` (освободит кэш сборки), при необходимости увеличить диск контейнера или перенести данные моделей на отдельный том.
5. **Ресурсы:** В compose закомментированы deploy.resources (limits/reservations). При 1 GB RAM контейнера возможны OOM при тяжёлых моделях или батчах; при необходимости увеличить память CT или выставить limits в compose.
---
## TODO по контейнеру 105
- [ ] **Логи Docker:** Включить ограничение размера логов: в `docker-compose.yml` добавить для сервиса `logging: driver: json-file options: max-size: "50m" max-file: "3"` или задать default в `/etc/docker/daemon.json`, перезапустить Docker и контейнер.
- [ ] **Мониторинг диска:** Следить за местом (df -h). Уже 74% — при достижении 85%+ выполнить `docker builder prune` и/или оценить увеличение диска. При желании — оповещение при заполнении выше порога.
- [ ] **Домен и NPM:** При необходимости настроить в NPM proxy для mini-lm.katykhin.ru → 192.168.1.105:8000, выпустить SSL. В клиентах использовать https и передавать X-API-Key.
- [ ] **Резервное копирование:** Регулярный бэкап критичных данных (оценка размеров на момент документации):
- **`/home/rag-service/data/models`** — кэш моделей (sentence-transformers, rubert и др.). ~734 MB. Восстановление: при потере модели скачаются заново при первом запросе, но бэкап ускоряет восстановление.
- **`/home/rag-service/data/vectors`** — векторы (vectors.npz). ~2 MB. Важно бэкапить, если векторы содержат уникальные данные и не воссоздаются автоматически.
- **`/home/rag-service/.env`** — секреты и настройки. Обязательно; не коммитить.
- **`/home/rag-service/docker-compose.yml`**, **Dockerfile**, при необходимости весь каталог **app/** и конфиги (pyproject.toml, env.example и т.д.) — для воспроизведения сборки. Размер кода порядка мегабайт.
Образ Docker бэкапить не обязательно (собирается из Dockerfile); при восстановлении на новом хосте: скопировать данные и код, задать .env, выполнить `docker compose build && docker compose up -d`.
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домен mini-lm.katykhin.ru, схема сети.
- [Контейнер 100 (nginx)](container-100.md) — NPM, через который проксируется mini-lm.katykhin.ru.

View File

@@ -0,0 +1,183 @@
# Контейнер 107 (Invidious): Invidious, Companion, PostgreSQL
Подробное описание LXC-контейнера **107** на Proxmox (192.168.1.107): Invidious (альтернативный фронтенд YouTube), Invidious Companion и PostgreSQL 14. Домен: video.katykhin.ru.
---
## Общие сведения
- **Хостнейм:** misc
- **IP:** 192.168.1.107/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 1 core, 2 GB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 107 -- bash` или по SSH на 192.168.1.107, если настроен.
Диск контейнера: 15 GB, занято ~2.1 GB (16%). Основной объём: образы и тома Docker (~0.8 GB), код Invidious в `/opt/invidious/` (~11 MB), данные PostgreSQL (~51 MB). Запас по месту большой, но при росте логов и БД всё равно стоит следить за заполнением (см. раздел «Логи и ротация» и TODO).
---
## Доступ и логины
- **Debian (CT 107):** логин `root` (пароль — в менеджере паролей или как настраивал при установке).
- **Invidious (веб):** http://192.168.1.107:3000 (или через NPM: https://video.katykhin.ru). Пользовательские аккаунты и настройки создаются в самом Invidious.
---
## Сервисы (Docker Compose)
Один проект: **/opt/invidious/docker-compose.yml** (внутри gitрепозитория Invidious: `/opt/invidious/`). Сеть: **invidious_default** (bridge).
| Контейнер | Образ | Порты (хост) | Назначение |
|--------------------------|------------------------------------------|--------------|------------|
| invidious-invidious-1 | quay.io/invidious/invidious:latest | 3000 | Веб-интерфейс Invidious, API |
| invidious-companion-1 | quay.io/invidious/invidious-companion | — (8282 внутри) | Companionсервис для запросов к YouTube |
| invidious-invidious-db-1 | postgres:14 | — | БД Invidious |
---
## 1. Invidious (основной сервис)
**Каталог:** `/opt/invidious/`
**Compose:** `docker-compose.yml` (лежит в корне репозитория).
**Порты:** 3000 (хост) → 3000 (контейнер). NPM (контейнер 100) проксирует https://video.katykhin.ru → 192.168.1.107:3000.
**Тома и конфиги:**
- Invidious не использует отдельные bindтома для конфигов/данных — данные хранятся в PostgreSQL (`invidious_postgresdata`), а конфиг задаётся через переменную `INVIDIOUS_CONFIG` в compose (inline YAML).
- Отдельных каталогов с логами Invidious на хосте нет — логи идут в stdout контейнера (см. раздел «Логи и ротация»).
**Основная конфигурация (в docker-compose.yml, секция `environment / INVIDIOUS_CONFIG`):**
- `db`: dbname=invidious, user=kemal, password=kemal, host=invidious-db, port=5432, check_tables=true.
- `invidious_companion`: URL сервиса companion (`http://companion:8282/companion`).
- `invidious_companion_key` и `SERVER_SECRET_KEY` (в companion) — общий секрет между Invidious и Companion (сейчас заданы прямо в compose; **не выкладывать в публичный репозиторий**).
- `external_port: 443`, `domain: "video.katykhin.ru"`, `https_only: true` — Invidious знает про внешний домен и порт, отдаёт ссылки на https.
- Прочие опции (feeds, captions, hmac_key, default_user_preferences и т.д.).
**Команды:**
```bash
cd /opt/invidious && docker compose up -d
docker logs invidious-invidious-1
curl -s http://127.0.0.1:3000/api/v1/stats
```
---
## 2. Invidious Companion
**Образ:** `quay.io/invidious/invidious-companion:latest`.
**Порты:** 8282 (внутри docker-сети). НСЛУШАЕТ напрямую на хосте; Invidious обращается к нему по имени `companion` в сети `invidious_default`.
**Тома:**
- volume `companioncache``/var/tmp/youtubei.js` (кэш jsресурсов YouTube / youtubei).
**Безопасность:**
- `SERVER_SECRET_KEY` совпадает с `invidious_companion_key` в конфиге Invidious — это shared secret для обмена.
- Контейнер запущен с `read_only: true`, `cap_drop: [ALL]`, `no-new-privileges:true` — хорошая практика sandboxing.
**Команды:**
```bash
docker logs invidious-companion-1
```
---
## 3. PostgreSQL (invidious-db)
**Образ:** postgres:14.
**Том:** volume `postgresdata``/var/lib/postgresql/data`. На хосте: `/var/lib/docker/volumes/invidious_postgresdata/_data` (~51 MB).
**Дополнительные mounts:**
- `/opt/invidious/config/sql``/config/sql` — SQLскрипты инициализации/миграций из репозитория Invidious (~40 KB).
- `/opt/invidious/docker/init-invidious-db.sh``/docker-entrypoint-initdb.d/init-invidious-db.sh` — скрипт инициализации БД при первом запуске.
**Переменные окружения:** POSTGRES_DB=invidious, POSTGRES_USER=kemal, POSTGRES_PASSWORD=kemal (заданы в compose; не публиковать).
**Команды:**
```bash
docker exec invidious-invidious-db-1 pg_isready -U kemal
docker exec invidious-invidious-db-1 psql -U kemal -d invidious -c '\\dt'
```
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|------|--------------------------|
| 3000 | Invidious (веб, API) |
Companion и PostgreSQL доступны только внутри docker-сети `invidious_default`.
---
## Логи и ротация
- **Invidious и Companion:** логи идут в stdout контейнеров и сохраняются драйвером Docker **json-file**. В compose для `invidious` и `companion` заданы опции:
- `max-size: "1G"`, `max-file: "4"` — максимум ~4 GB логов на контейнер. На момент проверки общий размер `/var/lib/docker` ~774 MB, запас по логам большой.
- **PostgreSQL:** контейнер `invidious-db` использует json-file **без ограничений** (`Config:{}`) — логи БД могут разрастаться (см. TODO).
**Системный logrotate** в CT — только стандартные правила (apt, dpkg, btmp, wtmp). Отдельных правил для Docker или PostgreSQL нет.
**Вывод:** для Invidious и Companion уже есть базовая защита от разрастания логов (1G×4), но для БД и общего Dockerдвижка ротация не настроена централизованно.
---
## Запуск и порядок поднятия
1. Зайти в каталог: `cd /opt/invidious`.
2. Проверить/при необходимости подредактировать `docker-compose.yml` (секция `INVIDIOUS_CONFIG`, домен video.katykhin.ru, секреты).
3. Запуск/перезапуск:
```bash
docker compose up -d
```
Порядок: сначала поднимается `invidious-db`, затем `invidious` (depends_on с healthcheck), параллельно Companion.
После изменения конфигурации (секция `INVIDIOUS_CONFIG` или окружения Companion/DB):
`cd /opt/invidious && docker compose up -d` — конфигурация применяется при перезапуске контейнеров.
---
## Уязвимости и риски
1. **Секреты и пароли в docker-compose.yml:**
В `INVIDIOUS_CONFIG` заданы:
- пароли БД (user/password kemal),
- `invidious_companion_key`,
- `hmac_key` и др. чувствительные значения.
Файл лежит только на сервере; его нельзя публиковать. Рекомендуется:
- ограничить права на `/opt/invidious/docker-compose.yml` (например chmod 600, владелец root),
- при переносе конфигурации использовать приватные репозитории или отдельные `.env`/секреты.
2. **PostgreSQL логи без лимитов:**
Контейнер `invidious-db` использует json-file без max-size/max-file — логи БД со временем могут занять существенный объём, особенно при ошибках или verboseрежиме (см. TODO).
3. **Доступ к Invidious:**
- В LAN сервис доступен по http://192.168.1.107:3000.
- Наружу следует пускать только через NPM (https://video.katykhin.ru), без прямого проброса порта 3000 на интернет.
4. **Обновления Invidious:**
В репозитории `/opt/invidious` лежит копия официального кода. Образ используется `latest` — при обновлении нужно внимательно следить за совместимостью БД и параметров, и перед апдейтом делать бэкап БД (см. TODO по бэкапам).
---
## TODO по контейнеру 107
- [ ] **Логи PostgreSQL:** Добавить ограничение логов для контейнера `invidious-invidious-db-1`:
либо через `logging` в `docker-compose.yml` (аналогично `invidious`/`companion`, но с меньшим лимитом, например `max-size: "200m"`, `max-file: "5"`), либо через глобальный `/etc/docker/daemon.json`. После изменения — перезапустить контейнер.
- [ ] **Права на конфиги:** Ограничить доступ к `docker-compose.yml` и, при необходимости, к другим файлам с секретами (chmod 600, владелец root), убедиться, что эти файлы не попадают в публичные репозитории.
- [ ] **Мониторинг диска:** Сейчас используется ~2.1 GB из 15 GB, но при росте логов/БД стоит настроить оповещение при заполнении >80% и периодически проверять `du -sh /var/lib/docker /var/lib/docker/volumes/invidious_postgresdata/_data`.
- [ ] **Резервное копирование:** Регулярный бэкап критичных данных (оценка размеров на момент документации):
- **`/var/lib/docker/volumes/invidious_postgresdata/_data`** — БД Invidious (~51 MB).
Рекомендуемый способ — логический дамп:
```bash
docker exec invidious-invidious-db-1 pg_dump -U kemal invidious > backup_invidious_$(date +%Y%m%d).sql
```
и хранить дампы вне контейнера (на Proxmoxхосте/внешнем хранилище).
- **`/opt/invidious`** — код Invidious, `docker-compose.yml`, `config/sql`, `docker/init-invidious-db.sh` (~11 MB).
Важно сохранить локальные правки (особенно секцию `INVIDIOUS_CONFIG` и домен/HTTPSнастройки).
- **`/var/lib/docker/volumes/invidious_companioncache/_data`** — кэш Companion (~4 KB). Бэкап не критичен; при потере восстановится автоматически.
- [ ] **Документация по обновлению:** Зафиксировать отдельной заметкой процедуру апдейта Invidious (pull нового образа, миграции, проверка конфигов и обратимости через бэкап БД).
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домен video.katykhin.ru, схема сети.
- [Контейнер 100 (nginx)](container-100.md) — NPM, через который проксируется video.katykhin.ru.

View File

@@ -0,0 +1,136 @@
# Контейнер 108 (Galene): Galene видеоконференции
Подробное описание LXC-контейнера **108** на Proxmox (192.168.1.108): сервер видеоконференций Galene (домен call.katykhin.ru). STUN/TURN вынесены на внешний VPS (coTURN), в контейнере — только Galene как systemd-сервис, без Docker.
---
## Общие сведения
- **Хостнейм:** galene
- **IP:** 192.168.1.108/24
- **ОС:** Debian 12 (bookworm)
- **Ресурсы:** 1 core, 256 MB RAM (из [архитектуры](../architecture/architecture.md))
- **Доступ:** с Proxmox — `pct exec 108 -- bash` или по SSH на 192.168.1.108, если настроен.
Диск контейнера: ~4 GB, занято ~1.2 GB (33%). Основной объём: система, код Galene в `/opt/galene/` (~6.6 MB), данные в `/opt/galene-data/` (~1.7 MB). Логи — в systemd journal (~8 MB). Следить за местом и ротацией journal (см. раздел «Логи и ротация» и TODO).
---
## Доступ и логины
- **Debian (CT 108):** логин `root`, пароль `Galene108!`.
- **Galene (веб):** https://call.katykhin.ru (через NPM → 192.168.1.108:8443). Вход в группы — по паролям, заданным в конфигах групп в `/opt/galene-data/groups/` (операторы и участники).
---
## Сервисы (systemd, без Docker)
| Сервис | Назначение | Порт (хост) |
|------------------|--------------------------------------------------|-------------|
| galene.service | Galene Videoconference Server (galene-server) | 8443 (HTTP) |
| coturn | Не запущен (disabled) — TURN на внешнем VPS | — |
| ssh, cron, postfix@- | Стандартные сервисы CT | 22, 25 |
Galene слушает на **0.0.0.0:8443** по HTTP (`-insecure`). TLS обеспечивает NPM на контейнере 100 (https://call.katykhin.ru → proxy на 192.168.1.108:8443).
---
## 1. Galene (galene.service)
**Unit:** `/etc/systemd/system/galene.service`
**Бинарник:** `/opt/galene-server` (собран из исходников в `/opt/galene/`).
**Рабочий каталог:** `/opt/galene-data`.
**Параметры запуска:** `-http 0.0.0.0:8443 -insecure -turn "" -static /opt/galene-data/static`
- `-insecure` — HTTP без TLS (TLS на NPM).
- `-turn ""` — встроенный TURN не используется; ICE-серверы заданы в `data/ice-servers.json` (внешний coTURN на VPS).
- Статика отдаётся из `/opt/galene-data/static`.
**Структура данных на хосте:**
- **`/opt/galene-data/`** — данные и конфиги:
- **`data/`** — глобальные настройки:
- `config.json` — proxyURL (например https://call.katykhin.ru/).
- `ice-servers.json` — список STUN/TURN (URL, username, credential для TURN на VPS). **Содержит креды TURN — не публиковать.**
- `cert.pem`, `key.pem` — локальные сертификаты (для внутренних нужд; внешний HTTPS через NPM).
- **`groups/`** — конфиги групп (по одному JSON на группу): имя файла вида `<groupname>-<suffix>.json`. В каждом файле: пользователи и пароли (операторы/участники), `wildcard-user`, `max-clients`, `allow-recording`, `autolock` и т.д. **Пароли пользователей групп хранятся в этих файлах — не публиковать.**
- **`static/`** — копия/кастомизация статики из `/opt/galene/static/` (HTML, CSS, JS для веб-клиента).
- **`/opt/galene/`** — исходный код Galene (репозиторий), бинарник `galene-server` собирается отсюда. При обновлении: пересборка и перезапуск сервиса.
**Команды:**
```bash
systemctl status galene
systemctl restart galene
journalctl -u galene.service -f
curl -s -k https://192.168.1.108:8443/ # или через NPM: https://call.katykhin.ru/
```
---
## 2. coTURN (не используется в CT)
Сервис **coturn** в контейнере установлен, но **disabled и inactive**. STUN/TURN для Galene вынесены на внешний сервер (VPS Миран: 185.147.80.190, см. [VPS Миран: боты и STUN/TURN](vps-miran-bots.md)). Клиенты получают список STUN/TURN из `ice-servers.json` в `/opt/galene-data/data/`.
При необходимости поднять TURN локально — настроить coturn и указать его в `ice-servers.json` или в параметрах galene-server.
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|------|----------------------------|
| 8443 | Galene (HTTP, TLS на NPM) |
| 22 | SSH |
| 25 | Postfix (localhost) |
---
## Логи и ротация
- **Galene:** логи пишутся в **stdout/stderr** и попадают в **systemd journal** (journalctl -u galene.service). Отдельных файловых логов в `/opt/galene-data/` нет. На момент проверки журнал занимает ~8 MB.
- **Ротация journal:** управляется настройками journald (например `/etc/systemd/journald.conf`: SystemMaxUse, MaxFileSec). Отдельного правила logrotate для Galene нет — ротация только за счёт journald. При долгой работе и активном трафике журнал может расти (см. TODO).
- **Системный logrotate** в CT — стандартные правила (apt, dpkg, btmp, wtmp). Для Galene отдельного файла логов нет.
**Риск:** при большом количестве подключений и ошибок объём journal может вырасти. Рекомендуется ограничить размер журнала в journald.conf и при желании настроить выгрузку логов Galene в файл с logrotate (см. TODO).
---
## Запуск и порядок поднятия
1. Убедиться, что доступны каталоги `/opt/galene` и `/opt/galene-data` и в `data/` есть `config.json`, `ice-servers.json`.
2. Запуск сервиса: `systemctl start galene` (или при загрузке CT — `systemctl enable galene` уже выполнен, т.к. сервис активен).
3. NPM на контейнере 100 должен проксировать https://call.katykhin.ru на 192.168.1.108:8443.
После смены конфигов в `/opt/galene-data/data/` или в `groups/`: `systemctl restart galene`. После обновления кода в `/opt/galene/` — пересобрать бинарник, заменить `/opt/galene-server` и перезапустить сервис.
---
## Уязвимости и риски
1. **Пароли и креды в конфигах:** В `/opt/galene-data/data/ice-servers.json` хранится TURN credential. В каждом файле в `/opt/galene-data/groups/*.json` — пароли пользователей (операторы, участники). Эти каталоги не должны попадать в публичный репозиторий. Ограничить права (например chmod 600 на файлы с паролями), хранить бэкапы в защищённом месте.
2. **Доступ по порту 8443:** Galene слушает на всех интерфейсах (0.0.0.0:8443). Из LAN доступ по http://192.168.1.108:8443. Снаружи доступ только через NPM (https://call.katykhin.ru). Не пробрасывать 8443 в интернет напрямую.
3. **Логи в journal:** Ротация только через journald; при необходимости ограничить SystemMaxUse и проверить, что старые логи не заполняют диск (см. TODO).
4. **Мало RAM (256 MB):** Контейнер с небольшим объёмом памяти; при большом числе одновременных участников возможны проблемы. При необходимости увеличить память CT в Proxmox.
---
## TODO по контейнеру 108
- [ ] **Ротация journal:** Проверить/задать в `/etc/systemd/journald.conf` параметры `SystemMaxUse=`, `MaxFileSec=` (или аналог), чтобы журнал не разрастался бесконечно. После изменений — `systemctl restart systemd-journald` (учёт потери текущего лога при рестарте).
- [ ] **Права на конфиги:** Ограничить доступ к файлам с паролями и кредами: `chmod 600` на `ice-servers.json`, на файлы в `groups/`. Владелец root.
- [ ] **Мониторинг диска:** Следить за местом (df -h) и размером журнала. При желании — оповещение при заполнении выше порога (например 80%).
- [ ] **Резервное копирование:** Регулярный бэкап критичных данных (оценка размеров на момент документации):
- **`/opt/galene-data`** — данные и конфиги: `data/` (config.json, ice-servers.json, cert.pem, key.pem), `groups/` (все JSON групп), `static/` при наличии кастомизаций. ~1.7 MB. **Обязательно;** содержит пароли и TURN credential — хранить бэкапы в защищённом месте, не публиковать.
- **`/opt/galene`** — исходный код и бинарник (или только скрипты сборки и версию). ~6.6 MB. Нужен для воспроизведения сборки galene-server; при использовании upstream репозитория можно восстанавливать из git, но локальные патчи стоит бэкапить.
- **`/etc/systemd/system/galene.service`** — unit-файл. Небольшой размер; включить в бэкап конфигов системы.
Восстановление: скопировать `/opt/galene-data` и при необходимости `/opt/galene`, установить unit, выполнить `systemctl daemon-reload && systemctl start galene`. TURN на VPS должен быть доступен и креды в `ice-servers.json` совпадать с настройками coTURN.
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров, домен call.katykhin.ru, схема сети.
- [Контейнер 100 (nginx)](container-100.md) — NPM, через который проксируется call.katykhin.ru.
- [VPS Миран (СПБ): боты и STUN/TURN](vps-miran-bots.md) — внешний coTURN для Galene (STUN/TURN сервер).

View File

@@ -0,0 +1,241 @@
# ВМ 200 (Immich): Immich, PostgreSQL, Redis, ML, deduper
Подробное описание **KVM-ВМ 200** на Proxmox (192.168.1.200): хост для Immich (фото/видео), PostgreSQL, Redis (Valkey), Immich Machine Learning (CUDA), upload-optimizer, power-tools, public-proxy и отдельный стек immich-deduper + Qdrant. Домен: immich.katykhin.ru. Данные и Docker размещены на отдельном диске `/mnt/data` (350 GB).
---
## Общие сведения
- **Тип:** KVM-виртуальная машина (управление: `qm` на Proxmox).
- **Имя ВМ:** immich
- **IP:** 192.168.1.200/24
- **ОС:** Debian 13 (trixie)
- **Ресурсы:** 3 core, 10 GB RAM, GPU (hostpci0 для VGA; ML-контейнер с NVIDIA).
- **Доступ:** SSH под пользователем **admin** (не root): `ssh admin@192.168.1.200` с хоста 192.168.1.150 или из LAN. Для выполнения команд с правами root: `sudo ...`.
**Диски:**
- **Корневой диск** (sda1): 35 GB, занято **~29 GB (87%)** — система, образы/кэш в пределах корня. **Критично:** мало свободного места; при росте логов или обновлениях возможны сбои. Следить за местом и логированием (см. TODO).
- **Данные** (sdb1): 344 GB, смонтирован в **/mnt/data**, занято ~177 GB (55%). Здесь: библиотека Immich, БД PostgreSQL, Docker root, containerd, Ollama, данные deduper.
---
## Доступ и логины
- **ВМ (Debian):** пользователь **admin** (вход по SSH-ключу или паролю; пароль задан при cloud-init, хранить в менеджере паролей). Root через `sudo`.
- **Immich (веб):** учётные записи — пользователи Immich (создаются в веб-интерфейсе). Доступ к сервисам:
| Сервис | Доступ | Адрес |
|--------------|---------------------|--------|
| Immich | Публичный (NPM) | https://immich.katykhin.ru |
| Power Tools | Публичный (Basic Auth в NPM) | https://immich-pt.katykhin.ru |
| Public Share | Публичный (NPM) | https://share.katykhin.ru |
| Deduper | Только LAN | http://192.168.1.200:8086 |
Логины и пароли Power Tools / Immich — в менеджере паролей; в открытую документацию не вносить.
---
## Сервисы (Docker Compose)
Два проекта:
1. **Immich**`/opt/immich/docker-compose.yml`. Сеть **immich_default**; дополнительно сеть **immich-deduper** (external) для доступа postgres к deduper.
2. **immich-deduper**`/opt/immich-deduper/docker-compose.yml`. Сеть **immich-deduper** (external), общая с Immich для доступа к БД.
| Контейнер | Образ / тег | Порты (хост) | Назначение |
|---------------------------|-------------------------------------------------------|------------------|------------|
| immich_upload_optimizer | miguelangel-nubla/immich-upload-optimizer:latest | 2283 | Прокси перед Immich (оптимизация загрузок); NPM смотрит сюда |
| immich_server | immich-app/immich-server:v2 | 2284→2283 | Основное приложение Immich |
| immich_postgres | immich-app/postgres:14-vectorchord... | — | PostgreSQL с расширениями (pgvector и др.) |
| immich_redis | valkey/valkey:9 | — | Кэш/очереди |
| immich_machine_learning | immich-app/immich-machine-learning:v2-cuda | — | ML (распознавание и т.д.), с GPU |
| immich_power_tools | varun-raj/immich-power-tools:latest | 8001→3000 | Дополнительные утилиты |
| immich_public_proxy | alangrainger/immich-public-proxy:latest | 8501→3000 | Публичный прокси к Immich |
| immich-deduper | razgrizhsu/immich-deduper:latest-cpu | 8086 | Поиск дубликатов |
| immich-deduper-qdrant | qdrant/qdrant:v1.16.3 | — | Векторная БД для deduper |
---
## 1. Immich (основной стек)
**Каталог:** `/opt/immich/`
**Compose:** `docker-compose.yml`, переменные из **.env** (не коммитить).
**Порты:** Внешний доступ в NPM настроен на **2283** (upload_optimizer). Дополнительно открыты: 2284 (server), 8001 (power-tools), 8501 (public-proxy).
**Пути из .env (на хосте):**
- **UPLOAD_LOCATION** — каталог загруженных файлов (фото/видео). На момент проверки: `/mnt/data/library` (~148 GB).
- **DB_DATA_LOCATION** — данные PostgreSQL. На момент проверки: `/mnt/data/postgres` (~657 MB).
**Тома (по умолчанию из .env):**
- `${UPLOAD_LOCATION}``/data` в immich_server (и в upload_optimizer через upstream).
- `${DB_DATA_LOCATION}``/var/lib/postgresql/data` в immich_postgres.
- model-cache (volume) → кэш моделей ML в immich_machine_learning.
- /etc/localtime — для времени.
**Переменные окружения (.env):** DB_PASSWORD, DB_USERNAME, DB_DATABASE_NAME, DB_HOST, DB_PORT, IMMICH_URL, IMMICH_API_KEY, EXTERNAL_IMMICH_URL, GEMINI_API_KEY (и др.). Файл содержит секреты — не публиковать, ограничить права (chmod 600).
**Команды:**
```bash
cd /opt/immich && docker compose up -d
docker logs immich_server
docker logs immich_upload_optimizer
```
---
## 2. Immich Machine Learning
Использует образ с **CUDA** и `deploy.resources.reservations.devices` (nvidia, count: 1). Кэш моделей в volume **model-cache**. Контейнер не публикует порты; общается с immich_server по внутренней сети.
---
## 3. Upload optimizer, power-tools, public-proxy
- **immich_upload_optimizer:** принимает трафик на 2283, проксирует на immich-server:2283. NPM проксирует https://immich.katykhin.ru на 192.168.1.200:2283.
- **power-tools:** веб-интерфейс на порту 8001 (внутри LAN).
- **immich_public_proxy:** порт 8501, прокси к immich-server:2283 (для публичных ссылок и т.п.).
---
## 4. PostgreSQL и Redis
- **immich_postgres:** данные в `/mnt/data/postgres`. Healthcheck включён. Подключение из deduper через сеть immich-deduper (database подключён к default и immich-deduper).
- **immich_redis:** Valkey 9, без постоянного тома в стандартной конфигурации (при перезапуске кэш сбрасывается).
---
## 5. immich-deduper
**Каталог:** `/opt/immich-deduper/`
**Compose:** `docker-compose.yml`, переменные из **.env**.
**Порты:** 8086 (хост).
**Тома (из .env):**
- **DEDUP_DATA** — каталог данных deduper (на момент проверки: `/opt/immich-deduper/data`, ~231 MB с учётом всего каталога). Внутри: кэш и данные Qdrant (`DEDUP_DATA/qdrant`).
- **IMMICH_PATH** — путь к библиотеке Immich только для чтения (`/mnt/data/library`).
- Подключение к БД Immich через переменные PSQL_* и сеть immich-deduper.
**Команды:**
```bash
cd /opt/immich-deduper && docker compose up -d
docker logs immich-deduper
```
---
## Порты (сводка на хосте)
| Порт | Сервис / примечание |
|-------|----------------------------------------|
| 2283 | Upload optimizer (основной вход для NPM) |
| 2284 | Immich server (прямой доступ) |
| 8001 | Power-tools |
| 8501 | Public proxy |
| 8086 | immich-deduper |
---
## Расширение диска данных (без даунтайма)
Диск данных ВМ (sdb1, /mnt/data) можно увеличить на Proxmox без остановки Immich. Пример: с 350 GB до 700 GB.
**1. На хосте Proxmox (192.168.1.150):** увеличить виртуальный диск:
```bash
qm resize 200 scsi1 +350G
```
**2. Внутри ВМ (ssh admin@192.168.1.200):** расширить раздел:
```bash
sudo growpart /dev/sdb 1
```
**3. Внутри ВМ:** расширить файловую систему (онлайн, без размонтирования):
```bash
sudo resize2fs /dev/sdb1
```
Операция занимает порядка 30 секунд; перезагрузка не требуется.
---
## Включение Machine Learning и Smart Search
После загрузки фото можно включить ML (распознавание, смарт-поиск). Предусловия: GPU passthrough в ВМ настроен и работает (`nvidia-smi` внутри ВМ), в compose для `immich-machine-learning` заданы `runtime: nvidia` и `deploy.resources.reservations.devices` (nvidia).
1. **Включить ML через API** (подставить свой API-ключ из .env или из веб-интерфейса Immich → Administration → API Keys):
```bash
curl -s "http://192.168.1.200:2284/api/system-config" -H "x-api-key: YOUR_API_KEY" | \
python3 -c "import sys,json; c=json.load(sys.stdin); c['machineLearning']['enabled']=True; print(json.dumps(c))" | \
curl -s -X PUT "http://192.168.1.200:2284/api/system-config" -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" -d @-
```
2. **Сменить CLIP-модель** для поиска на русском: Immich UI → Administration → Settings → Machine Learning → Smart Search → Model Name: `nllb-clip-large-siglip__mrl` → Save.
3. **Язык пользователя:** в настройках пользователя Immich выставить русский (NLLB-модель ожидает запросы на языке из настроек).
4. **Запустить переиндексацию:** Administration → Jobs → Smart Search → нажать «All». На большом объёме фото (порядка десятков тысяч) на GPU займёт 2030 минут.
5. **По желанию снизить RAM ВМ** до 8 GB после индексации (на хосте Proxmox): `qm set 200 --memory 8192 --cores 3`.
---
## Логи и ротация
- **Docker:** данные Docker (образы, контейнеры, overlay) хранятся в **/mnt/data/docker** (Docker Root Dir). Логи контейнеров — драйвер **json-file** без ограничения размера и количества файлов (Config:{} у immich_server и immich_postgres). При активной работе логи могут разрастаться и занимать место на **корневом** разделе (если логи пишутся на корень) или в overlay на /mnt/data — уточнить расположение логов контейнеров (часто в /mnt/data/docker/containers). В любом случае ограничение логов не задано (см. TODO).
- **Системный logrotate:** стандартные правила (apt, dpkg, cloud-init, unattended-upgrades, wtmp). Отдельных правил для Immich или Docker нет.
**Риск:** корневой диск заполнен на 87%. Рост логов, обновления и кэш могут привести к нехватке места. Необходимо ограничить логи Docker и следить за местом на корне (см. TODO).
---
## Запуск и порядок поднятия
1. Создать внешнюю сеть (если ещё нет):
`docker network create immich-deduper`
2. Immich:
`cd /opt/immich && docker compose up -d`
Порядок: database, redis → immich-server (и ML, upload_optimizer, power_tools, public_proxy).
3. Deduper:
`cd /opt/immich-deduper && docker compose up -d`
После смены .env или compose: перезапуск соответствующих стеков. Обновление образов: `docker compose pull && docker compose up -d` (для Immich при обновлении проверять совместимость БД и миграции).
---
## Уязвимости и риски
1. **Секреты в .env:** В `/opt/immich/.env` и `/opt/immich-deduper/.env` хранятся пароли БД, API-ключи (IMMICH_API_KEY, GEMINI_API_KEY), креды для deduper (PSQL_*). Файлы не должны попадать в публичный репозиторий. Ограничить права (chmod 600), хранить бэкапы в защищённом месте.
2. **Корневой диск 87%:** Критично мало свободного места. При 100% возможны сбои обновлений и работы сервисов. Срочно: освободить место и/или перенести часть данных на /mnt/data, ограничить логи Docker (см. TODO).
3. **Логи Docker без лимитов:** Ротация не настроена — возможен рост логов и заполнение диска.
4. **Доступ по портам:** Сервисы доступны по 2283, 2284, 8001, 8501, 8086 из LAN. Снаружи доступ только через NPM (https://immich.katykhin.ru → 2283). Не пробрасывать порты напрямую в интернет.
5. **GPU и PCI-passthrough:** ВМ использует hostpci0 (VGA). Убедиться, что драйверы NVIDIA и доступ к GPU корректны для immich_machine_learning.
---
## TODO по ВМ 200
- [ ] **Корневой диск:** Снизить использование корня (87%). Варианты: перенести логи Docker на /mnt/data (если сейчас пишутся на корень), очистить старые образы/кэш (`docker system prune` с осторожностью), увеличить размер корневого диска ВМ в Proxmox. Настроить мониторинг и оповещение при заполнении >90%.
- [ ] **Логи Docker:** Включить ограничение размера логов для всех контейнеров Immich и deduper: в `docker-compose.yml` добавить для каждого сервиса `logging: driver: json-file options: max-size: "100m" max-file: "3"` или задать default в `/etc/docker/daemon.json`. Убедиться, что Docker Root Dir остаётся на /mnt/data и логи не пишутся на корень. После изменений перезапустить контейнеры.
- [ ] **Права на конфиги:** Ограничить доступ к .env (chmod 600), не коммитить в публичные репозитории.
- [ ] **Резервное копирование:** Регулярный бэкап критичных данных (оценка размеров на момент документации):
- **`/mnt/data/library`** — библиотека Immich (фото, видео, превью). ~148 GB. Основной объём; бэкап обязателен (внешний диск, сетевое хранилище).
- **`/mnt/data/postgres`** — данные PostgreSQL Immich. ~657 MB. Для консистентного бэкапа предпочтительно дамп:
`docker exec immich_postgres pg_dump -U <DB_USERNAME> <DB_DATABASE_NAME> > backup_immich_$(date +%Y%m%d).sql` (подставить из .env). Хранить дампы вне ВМ.
- **`/opt/immich`** — docker-compose.yml, .env (секреты), hwaccel.ml.yml. ~20 KB. Обязательно; .env не коммитить.
- **`/opt/immich-deduper`** — docker-compose.yml, .env, каталог data (данные и кэш Qdrant). ~231 MB. Восстановление deduper возможно заново, но данные индексов — в data.
- **`/mnt/data/docker`** — образы и метаданные контейнеров (~16 GB). При восстановлении ВМ образы можно заново скачать; при необходимости бэкапить только метаданные томов или полный каталог.
- **`/mnt/data/ollama`** — данные Ollama (~4.1 GB). Бэкапить при использовании Ollama на этой ВМ.
Учитывать, что /mnt/data смонтирован с отдельного диска (tank или аналог в Proxmox); при бэкапе с хоста включить этот диск или снапшоты.
- [ ] **Документация по обновлению Immich:** Зафиксировать процедуру обновления (версия в IMMICH_VERSION, backup БД, docker compose pull, миграции, откат при сбое).
---
## Связь с другими документами
- [Архитектура и подключение](../architecture/architecture.md) — таблица контейнеров и ВМ, домен immich.katykhin.ru, схема сети.
- [Контейнер 100 (nginx)](container-100.md) — NPM, через который проксируется immich.katykhin.ru.
- [Paperless + Ollama: поиск по документам](paperless-ollama.md) — использование Ollama (обычно на этой ВМ) для ответов по документам из Paperless.

View File

@@ -0,0 +1,82 @@
# Paperless + Ollama: поиск по документам Paperless-ngx
Скрипт **paperless-ollama-ask.py** позволяет задавать вопросы по документам из Paperless-ngx (контейнер 104) и получать ответы от модели Ollama (обычно на ВМ 200). Работает так: ищет документы по тексту (OCR), собирает выдержки и подставляет их в промпт для локальной LLM.
---
## Требования
- Python 3.9+
- Запущенный **Paperless-ngx** (см. `container-104.md`) с доступным API
- Запущенный **Ollama** (обычно на ВМ 200, см. `container-200.md`)
Скрипт хранится в репозитории в `homelab/paperless-ollama-ask.py`, документация — в этом файле.
---
## Переменные окружения
| Переменная | Обязательная | По умолчанию | Пример |
|----------------------|--------------|------------------------|----------------------------------|
| `PAPERLESS_URL` | да | — | `http://192.168.1.104:8000` |
| `PAPERLESS_TOKEN` | да | — | токен API из Paperless |
| `OLLAMA_URL` | нет | `http://localhost:11434` | `http://192.168.1.200:11434` |
| `OLLAMA_MODEL` | нет | `saiga` | имя модели в Ollama |
| `PAPERLESS_MAX_DOCS` | нет | `5` | максимум документов в промпте |
**PAPERLESS_TOKEN:** берётся в веб-интерфейсе Paperless: профиль пользователя → токен API (см. документацию Paperless-ngx).
---
## Как это работает
1. Скрипт выполняет поиск в Paperless по строке запроса (full-text по OCR).
2. Берёт до `PAPERLESS_MAX_DOCS` подходящих документов.
3. Собирает выдержки/полный текст и формирует промпт для модели Ollama.
4. Отправляет промпт на `OLLAMA_URL` и выводит ответ в stdout.
---
## Примеры запуска
```bash
cd homelab
export PAPERLESS_URL="http://192.168.1.104:8000" # контейнер 104
export PAPERLESS_TOKEN="твой_токен_из_Paperless"
# Если Ollama на ВМ 200:
export OLLAMA_URL="http://192.168.1.200:11434"
# Вопросы по документам
python3 paperless-ollama-ask.py "номер паспорта?"
python3 paperless-ollama-ask.py "когда истекает договор?"
```
---
## Где запускать
- **На ВМ с Ollama (обычно ВМ 200):**
- `OLLAMA_URL=http://localhost:11434`
- `PAPERLESS_URL` — адрес контейнера 104 (`http://192.168.1.104:8000` или домен, который проксирует NPM).
- **На другой машине (например, твой ноут):**
- `PAPERLESS_URL` и `OLLAMA_URL` указывают на IP/домены Paperless и Ollama.
- Учесть доступность портов и фаервол.
---
## Безопасность и ограничение доступа
- **Токен Paperless** даёт доступ к документам — хранить его только в приватных местах (env, .env вне репозитория).
- **Ollama** обычно слушает на 11434; при пробросе наружу стоит ограничить доступ (файрвол, VPN).
- Запросы и выдержки из документов уходят в локальную модель; при использовании удалённых/облачных моделей учитывать конфиденциальность.
---
## Связь с другими документами
- [Контейнер 104 (Paperless)](container-104.md) — где крутится Paperless-ngx и какие порты/тома используются.
- [ВМ 200 (Immich)](container-200.md) — может одновременно работать как хост для Ollama (порт 11434).