Files
router-lists-ui/DOCKER.md
T
denozord cf3437c70c
Publish Docker image / build-and-push (push) Successful in 2m13s
Update Docker documentation and README for SQLite storage and environment variables
- Enhanced Docker.md with detailed instructions on building and running Docker images, including environment variable requirements and tag usage.
- Updated README.md to reflect the current architecture using SQLite for data storage and clarified environment variable settings for backend and frontend operations.
- Removed references to AWS S3, emphasizing local storage for MikroTik backups and SQLite database management.

Made-with: Cursor
2026-04-26 01:45:43 +07:00

214 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Docker Images
Образ собирается из [`Dockerfile.fast`](Dockerfile.fast) (многостадийная сборка: Vite frontend + `npm ci` backend, рантайм **distroless** Node 20). В Gitea Actions используется тот же файл (см. [`.gitea/workflows/docker-publish.yml`](.gitea/workflows/docker-publish.yml)).
## Теги в реестре `git.shts.su`
Замените `[repository]` на путь репозитория в Gitea (например `denozord/router-lists-ui`).
| Ветка (триггер push) | Образы в реестре |
|----------------------|-------------------|
| **main** (и v4, v3 и т.д. из workflow) | `git.shts.su/[repository]:latest` и `git.shts.su/[repository]:<полный-sha>` |
| **v5** | **только** `git.shts.su/[repository]:v5` и `git.shts.su/[repository]:v5-<полный-sha>` — тег **`latest` с ветки v5 не публикуется** |
| **tabler** | см. отдельный workflow `docker-publish-tabler.yml`, если включён |
Пин на коммит: используйте тег с суффиксом `-<sha>`; «плавающий» тег ветки (`:v5` или `:latest`) всегда указывает на последнюю успешную сборку.
## Запуск (production)
### Общие рекомендации
1. **Данные на хосте** — смонтируйте том для SQLite и каталог бэкапов MikroTik, иначе при удалении контейнера пропадут БД и `.rsc`.
2. **Переменные** — минимум `ENCRYPTION_KEY`; для справочников и UI — `EVOBGP_API_URL` и `EVOBGP_API_TOKEN`; при необходимости `CORS_ORIGINS`, `PORT`.
3. **Рантайм distroless** — внутри образа **нет** `/bin/bash` и пакетного менеджера; отладка через `docker logs` / метрики. Интерактивная оболочка недоступна.
### Основная линия (`:latest`)
```bash
docker run -d \
--name router-lists-ui \
-p 3001:3001 \
-e ENCRYPTION_KEY=<64-hex> \
-e EVOBGP_API_URL=https://evobgp.example/v1 \
-e EVOBGP_API_TOKEN=<token> \
-e SQLITE_PATH=/data/router-lists.db \
-e MIKROTIK_BACKUP_DIR=/data/backups/mikrotik \
-v router-lists-data:/data \
git.shts.su/[repository]:latest
```
Каталог `/data` на томе должен быть доступен пользователю **nonroot** (образ distroless); при ошибках прав создайте том заранее или используйте bind-mount с `chown` под UID образа (обычно `65532` у nonroot).
### Ветка v5 (только теги `v5` / `v5-<sha>`)
```bash
docker pull git.shts.su/[repository]:v5
docker run -d \
--name router-lists-ui-v5 \
-p 3002:3001 \
-e ENCRYPTION_KEY=<64-hex> \
-e EVOBGP_API_URL=https://evobgp.example/v1 \
-e EVOBGP_API_TOKEN=<token> \
-e SQLITE_PATH=/data/router-lists.db \
-e MIKROTIK_BACKUP_DIR=/data/backups/mikrotik \
-v router-lists-v5-data:/data \
git.shts.su/[repository]:v5
```
Чтобы зафиксировать конкретный коммит:
```bash
docker run -d ... git.shts.su/[repository]:v5-1c6e6ab...
```
### Tabler-ветка (если публикуется отдельным workflow)
```bash
docker run -d \
--name router-lists-ui-tabler \
-p 3003:3001 \
--env-file ./backend/.env \
-v router-lists-tabler-data:/data \
git.shts.su/[repository]:tabler
```
## Обновление образа
### latest
```bash
docker pull git.shts.su/[repository]:latest
docker stop router-lists-ui && docker rm router-lists-ui
# затем снова docker run ... как выше
```
### v5
```bash
docker pull git.shts.su/[repository]:v5
docker stop router-lists-ui-v5 && docker rm router-lists-ui-v5
docker run -d ... git.shts.su/[repository]:v5
```
## Docker Compose
Пример **одной** службы на `latest` с томом данных (подставьте свой `image:` и при необходимости `env_file`):
```yaml
services:
router-lists-ui:
image: git.shts.su/[repository]:latest
container_name: router-lists-ui
ports:
- "3001:3001"
restart: unless-stopped
environment:
NODE_ENV: production
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
EVOBGP_API_URL: ${EVOBGP_API_URL}
EVOBGP_API_TOKEN: ${EVOBGP_API_TOKEN}
SQLITE_PATH: /data/router-lists.db
MIKROTIK_BACKUP_DIR: /data/backups/mikrotik
volumes:
- router-lists-data:/data
volumes:
router-lists-data:
```
Отдельный сервис для **v5** — тот же фрагмент, но `image: git.shts.su/[repository]:v5`, другой `container_name` и при желании отдельный volume.
## Переменные окружения (контейнер)
| Переменная | Описание | Обязательная |
|------------|----------|----------------|
| `ENCRYPTION_KEY` | AES-256 для IPSec и паролей MikroTik (64 hex) | **Да** |
| `EVOBGP_API_URL` | Базовый URL API EvoBGP (серверный прокси `/api/evobgp` и бэкенд-справочники) | По сценарию |
| `EVOBGP_API_TOKEN` | Bearer к EvoBGP | По сценарию |
| `SQLITE_PATH` | Путь к файлу SQLite внутри контейнера (персистентный том) | Рекомендуется явно задать, напр. `/data/router-lists.db` |
| `MIKROTIK_BACKUP_DIR` | Каталог бэкапов `.rsc` на диске | Рекомендуется с томом, напр. `/data/backups/mikrotik` |
| `PORT` | Порт HTTP внутри контейнера | Нет (по умолчанию `3001`) |
| `CORS_ORIGINS` | Список Origin через запятую | Нет |
| `LOG_LEVEL` | Уровень логов pino | Нет |
`ENCRYPTION_KEY` должен быть **один и тот же** между перезапусками, иначе не расшифровать уже сохранённые секреты.
### EvoBGP и reverse proxy (nginx)
Запросы UI идут на тот же origin: `/api/evobgp/…` обрабатывает **Node** внутри образа. Если перед приложением стоит **nginx**, нужно проксировать префикс `/api` на Node **без потери** сегмента `/api` в URI.
**Рекомендуемый вариант** (путь `/api/…` сохраняется):
```nginx
location /api/ {
proxy_pass http://127.0.0.1:3001/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
```
**Типичная ошибка**: `proxy_pass http://127.0.0.1:3001/;` — nginx срезает `/api`. В коде есть запасной маршрут на `/evobgp`, но лучше исправить nginx.
**Проверка**: `GET http://<хост>:<порт>/api/evobgp` → JSON вида `{"ok":true,"proxy":true,"evobgpConfigured":true}`.
## Генерация `ENCRYPTION_KEY`
```bash
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```
## Мониторинг
```bash
docker logs -f router-lists-ui
docker stats router-lists-ui
```
## Локальная сборка (как в CI)
```bash
docker build -f Dockerfile.fast -t router-lists-ui:local .
docker run --rm -p 3001:3001 --env-file ./backend/.env -v $(pwd)/data:/data \
-e SQLITE_PATH=/data/router-lists.db \
-e MIKROTIK_BACKUP_DIR=/data/backups/mikrotik \
router-lists-ui:local
```
(PowerShell на Windows: вместо `$(pwd)` используйте путь к каталогу данных.)
## CI/CD (Gitea Actions)
- [`.gitea/workflows/docker-publish.yml`](.gitea/workflows/docker-publish.yml) — пуш в перечисленные ветки (включая **v5**): сборка и push в `git.shts.su`.
- Для **v5** в реестр уходят **только** теги `v5` и `v5-<sha>` (без `latest`).
- Остальные ветки из списка workflow — `latest` и тег по SHA.
Шаг **Trigger container update webhook** (если задан `secrets.portainer_webhook`) выполняется после сборки; при ошибке шаг не валит job (`continue-on-error: true`).
## Безопасность и сеть
```bash
docker network create router-lists-net
docker run -d --network router-lists-net ... git.shts.su/[repository]:latest
```
Ограничение ресурсов:
```bash
docker run -d --memory=512m --cpus=0.5 ... git.shts.su/[repository]:latest
```
## Устранение неполадок
```bash
docker ps -a --filter name=router-lists-ui
docker restart router-lists-ui
docker image prune -f
```
---
**Замените `[repository]`** на актуальный путь репозитория в Gitea (например `denozord/router-lists-ui`).