Skip to main content

Установка UMNI Server в среде виртуализации Proxmox VE на Debian 13 + Docker

В этой статье пойдет речь об установке UMNI Server в среде Proxmox VE (9.2). Работы будем проводить в контейнере LXC с включенным nesting и выключенным Unprivileged container.

Подготовка окружения

В качестве контейнера используем шаблон Debian 13 (https://docs.docker.com/engine/install/debian/).

После создания LXC обновите пакеты

su
apt update
apt upgrade

Теперь необходимо установить docker и docker-compose

# Add Docker's official GPG key:
apt update
apt install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

apt update

Теперь установим Docker, docker-compose

apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Проверка, что Docker запущен 

systemctl status docker

Установка UMNI Server

Создайте каталог, в котором будет находиться UMNI Server. Структура файлов для минимального старта такая:

umnu-ecosystem/                  <- любой каталог, где лежат файлы ниже
├── docker-compose.release.yml   # обязательно: запускает контейнеры из образов
├── nginx.conf                   # обязательно: монтируется в frontend, без него контейнер не стартует
├── env_config/
│   └── .env                     # обязательно: БД + настройки backend (сюда пишется ENCRYPTION_KEY)
├── .env                         # опционально: интерполяция compose (WEB_PORT, DB_NAME, ...)
├── storage/                     # внутренние данные; создаётся автоматически
├── logs/                        # логи backend; создаётся автоматически
└── plugins/
    └── custom/                  # пользовательские плагины

Создадим папку /opt/umni-ecosystem:

mkdir /opt/umni-ecosystem -p

Теперь создадим docker-compose.release.yml

cd /opt/umni-ecosystem
nano docker-compose.release.yml

Вставьте в него следующий код

services:
  postgres:
    image: postgres:16-alpine
    container_name: umni_postgres
    restart: unless-stopped
    env_file:
      - ./env_config/.env
    environment:
      TZ: Europe/Moscow
      POSTGRES_DB: ${DB_NAME:-umni}
      POSTGRES_USER: ${DB_USER:-postgres}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres}"]
      interval: 10s
      timeout: 5s
      retries: 5

  backend:
    image: ${IMAGE_OWNER:-sazanof}/umni-ecosystem-backend:${IMAGE_TAG:-latest}
    container_name: umni_backend
    restart: unless-stopped
    expose:
      - "8000"
    depends_on:
      postgres:
        condition: service_healthy
    env_file:
      - ./env_config/.env
    environment:
      DB_HOST: postgres
      DB_USER: ${DB_USER:-postgres}
      DB_PASSWORD: ${DB_PASSWORD:-postgres}
      DB_NAME: ${DB_NAME:-umni}
      DB_PORT: ${DB_PORT:-5432}
      LOG_LEVEL: ${LOG_LEVEL:-INFO}
      LOG_DIR: /app/logs
      STORAGE_HOST_BASE: ${STORAGE_HOST_BASE:-/host}
      TZ: Europe/Moscow
    volumes:
      - ./logs:/app/logs
      # .env монтируется на запись: приложение само хранит ENCRYPTION_KEY.
      - ./env_config:/app/env_config
      - ./storage:/app/storage
      - ./plugins/custom:/app/plugins/custom
      # Хранилища хоста. Путь в storages задаётся ХОСТОВЫЙ (например "D:\CameraData"),
      # backend сам переведёт его в контейнерный: "<STORAGE_HOST_BASE>/D/CameraData".
      #
      # Windows-хост (Docker Desktop): монтируем весь диск в /host/<буква>.
      # - type: bind
      #   source: 'D:\'
      #   target: /host/D
      #
      # Linux-хост: путь в storages задаётся контейнерный, как в маунте ниже.
      # - type: bind
      #   source: /mnt/rec
      #   target: /mnt/rec
    networks:
      - app-network

  frontend:
    image: ${IMAGE_OWNER:-sazanof}/umni-ecosystem-frontend:${IMAGE_TAG:-latest}
    container_name: umni_frontend
    restart: unless-stopped
    ports:
      - "${WEB_PORT:-80}:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:
    driver: bridge

Монтирование своих директорий и дисков

Если у вас в системе есть несколько дисков и вы хотите добавить их как кастомное хранилище, например для камер, то необходимо добавить соответствующий блок в  docker-compose.release.yml

Пример: узнаем сколько томов LVM и куда примонтированы (актуально для LXC):

root@umni-ecosystem:/opt/umni-ecosystem# df -h
Filesystem                                     Size  Used Avail Use% Mounted on
/dev/mapper/data--ssd--500gb-vm--106--disk--0   20G  1.2G   18G   7% /
/dev/mapper/data--hdd--1tb-vm--106--disk--0     35G  2.1M   33G   1% /mnt/umni-data

Редактируем docker-compose.release.yml

- type: bind
  source: /mnt/umni-data
  target: /mnt/umni-data

 

Создайте недостающие директории и файлы

mkdir env_config storage logs

Создайте файл env_config/.env

APP_MODE=production
DB_HOST=postgres
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=ecosystem
DB_PORT=5432
LOG_LEVEL=debug
DEBUG_MODE=app,cameras,devices,rules,mqtt,services,storages,systeminfo,scheduler,tasks,websockets,notifications,plugins

Создайте .env на основе .env.example

# Скопируйте этот файл в .env:  cp .env.example .env
# ДЕРЖИТЕ ЗНАЧЕНИЯ В СИНХРОНЕ С env_config/.env (backend).
# Этот файл используется ТОЛЬКО для интерполяции переменных docker compose
# (имя БД, порт фронтенда и т.п.) и НЕ передаётся в контейнеры напрямую.

# Postgres, создаваемая контейнером postgres
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=ecosystem
DB_PORT=5432

# Порт, на котором наружу будет доступен веб-интерфейс (http://localhost:WEB_PORT)
WEB_PORT=80

# Уровень логирования backend (INFO/DEBUG)
LOG_LEVEL=INFO

# Корень, куда монтируются диски хоста (backend переводит D:\... -> /host/D/...)
STORAGE_HOST_BASE=/host