Files
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

9.0 KiB
Raw Permalink Blame History

Docker Images

Образ собирается из Dockerfile.fast (многостадийная сборка: Vite frontend + npm ci backend, рантайм distroless Node 20). В Gitea Actions используется тот же файл (см. .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)

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>)

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

Чтобы зафиксировать конкретный коммит:

docker run -d ... git.shts.su/[repository]:v5-1c6e6ab...

Tabler-ветка (если публикуется отдельным workflow)

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

docker pull git.shts.su/[repository]:latest
docker stop router-lists-ui && docker rm router-lists-ui
# затем снова docker run ... как выше

v5

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):

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/… сохраняется):

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

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Мониторинг

docker logs -f router-lists-ui
docker stats router-lists-ui

Локальная сборка (как в CI)

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 — пуш в перечисленные ветки (включая 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).

Безопасность и сеть

docker network create router-lists-net
docker run -d --network router-lists-net ... git.shts.su/[repository]:latest

Ограничение ресурсов:

docker run -d --memory=512m --cpus=0.5 ... git.shts.su/[repository]:latest

Устранение неполадок

docker ps -a --filter name=router-lists-ui
docker restart router-lists-ui
docker image prune -f

Замените [repository] на актуальный путь репозитория в Gitea (например denozord/router-lists-ui).