# Публикация образов на Docker Hub Назначение — дать возможность любому развернуть окружение из готовых образов, без клонирования исходников и сборки (`docker-compose.release.yml`). ## Что публикуется | Репозиторий Docker Hub | Содержимое | |----------------------------------|-------------------------------------| | `/umni-ecosystem-backend` | FastAPI-бэкенд (см. `umni-ecosystem-backend/Dockerfile`) | | `/umni-ecosystem-frontend` | Vue-фронтенд + nginx (см. `umni-ecosystem-frontend/Dockerfile`) | Теги на каждый релиз: `vX.Y.Z` (имя git-тега) и `latest`. Сборка мультиархная: `linux/amd64`, `linux/arm64`. ``` docker pull /umni-ecosystem-backend:v1.0.0 ``` ## Способ 1. Ручная публикация Секреты не нужны, достаточно учётки Docker Hub. ```powershell cd C:\Develop\UMNI\Ecosystem docker login # логин Docker Hub # сборка обоих образов docker compose build # тегирование под ваш аккаунт docker tag ecosystem-backend /umni-ecosystem-backend:v1.0.0 docker tag ecosystem-backend /umni-ecosystem-backend:latest docker tag ecosystem-frontend /umni-ecosystem-frontend:v1.0.0 docker tag ecosystem-frontend /umni-ecosystem-frontend:latest # публикация docker push /umni-ecosystem-backend:v1.0.0 docker push /umni-ecosystem-backend:latest docker push /umni-ecosystem-frontend:v1.0.0 docker push /umni-ecosystem-frontend:latest ``` ### Мультиарх за один шаг (buildx) ```powershell docker buildx build --platform linux/amd64,linux/arm64 ` -t /umni-ecosystem-backend:v1.0.0 -t /umni-ecosystem-backend:latest ` --push ./umni-ecosystem-backend docker buildx build --platform linux/amd64,linux/arm64 ` -t /umni-ecosystem-frontend:v1.0.0 -t /umni-ecosystem-frontend:latest ` --push ./umni-ecosystem-frontend ``` ## Способ 2. GitHub Actions (рекомендуется) В каждом из репозиториев (`umni-ecosystem-backend`, `umni-ecosystem-frontend`) лежит `.github/workflows/docker-publish.yml`. ### Что он делает - Загружает код репозитория; - поднимает QEMU + Buildx (сборка под `amd64` и `arm64`); - логинится в Docker Hub по секретам; - собирает и публикует образ репозитория с тегами `<имя тега>` и `latest`. ### Когда срабатывает - **Пуш git-тега вида `v*`** (например `v1.0.0`). Обычные коммиты/пуши в ветки **не** отправляют образы. - **По кнопке «Run workflow»** (вкладка Actions → ручной запуск). ### Настройка один раз 1. В Docker Hub создайте репозитории `umni-ecosystem-backend`, `umni-ecosystem-frontend` (публичные или приватные — как хотите). 2. В **обоих** GitHub-репозиториях добавьте секреты Settings → Secrets and variables → Actions: - `DOCKERHUB_USERNAME` — ваш логин; - `DOCKERHUB_TOKEN` — Access Token с правами `Read/Write` (Account Settings → Security → Tokens). 3. Создайте тег и запушьте его: ```bash git tag v1.0.0 git push origin v1.0.0 ``` Workflow соберёт и опубликует оба образа автоматически. ### Особенности - Собирает **один репозиторий** (backend или frontend): build-context каждого — его каталог. - Корень `C:\Develop\UMNI\Ecosystem` git-репозиторием не является, поэтому CI размещён в самих подрепозиториях; а compose-файлы и эта документация публикуются отдельно. ## Развёртывание пользователем из образов ### Минимальный набор файлов и структура каталогов В любом каталоге на целевой машине (Windows/Linux/Docker Desktop/VM) достаточно: ``` deploy/ <- любой каталог, где лежат файлы ниже ├── docker-compose.release.yml # обязательно: запускает контейнеры из образов (host-режим) ├── nginx.host.conf # обязательно: монтируется в frontend, без него контейнер не стартует ├── env_config/ │ └── .env # обязательно: БД + настройки backend (сюда пишется ENCRYPTION_KEY) ├── .env # опционально: интерполяция compose (WEB_PORT, DB_NAME, ...) ├── storage/ # внутренние данные; создаётся автоматически ├── logs/ # логи backend; создаётся автоматически └── plugins/ └── custom/ # пользовательские плагины ``` | Файл | Назначение | |------|------------| | `docker-compose.release.yml` | Поднимает `postgres`, `backend`, `frontend` из Docker Hub (без сборки). `backend` и `frontend` работают в `network_mode: host`, `postgres` — на bridge `app-network`. | | `nginx.host.conf` | Раздаёт SPA и проксирует `/api/*` на `127.0.0.1:8000` (backend в сети хоста). Обязателен как bind-mount. | | `env_config/.env` | Параметры БД и backend. Монтируется в `/app/env_config` **на запись** — сюда backend сам сохраняет `ENCRYPTION_KEY`. | | `.env` (в корне) | Значения для интерполяции compose: `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_PORT`, `LOG_LEVEL`, `STORAGE_HOST_BASE`. В release (host-режим) `WEB_PORT` не используется: nginx слушает 80 на хосте. Если хватает значений по умолчанию — можно не создавать. | | `storage/`, `logs/`, `plugins/custom/` | Bind-каталоги; при отсутствии Docker создаёт их пустыми. | ### Шаги на Linux-VM ```bash # 1. Подготовить каталог и файлы (см. таблицу выше) mkdir -p env_config storage logs plugins/custom cp nginx.host.conf . ; cp docker-compose.release.yml . # положить env_config/.env (примеры ключей — в DOCKER.md) # 2. ПРАВА: контейнер backend работает от UID 1000 (appuser). # Без этого он не сможет писать логи и обновлять ENCRYPTION_KEY в .env. sudo chown -R 1000:1000 env_config logs storage plugins # 3. (опционально) Интернет-медиа: устройства шлют syslog на UDP 514 и находят # сервис ``_umni_api._tcp.local.`` (mDNS) по multicast. Backend в host-режиме # видит LAN напрямую, но не-root-процессу (UID 1000) нужен низкий порт 514: echo 'net.ipv4.ip_unprivileged_port_start=0' | sudo tee /etc/sysctl.d/99-umni.conf sudo sysctl --system # 4. Запуск docker compose -f docker-compose.release.yml pull # подтянуть образы (рекомендуется) docker compose -f docker-compose.release.yml up -d docker compose -f docker-compose.release.yml ps # все три контейнера Healthy ``` Откройте `http://` и пройдите мастер установки (nginx слушает порт 80 на хосте — проверьте, что он открыт в фаерволе VM). Проверка API: `GET http:///api/health` → `{"status":"healthy", ...}`. Проверка mDNS из host-сети (backend в host-режиме = сеть хоста): ```bash docker exec umni_backend python -c "import socket;s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM);s.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,2);s.sendto(b't',('224.0.0.251',5353));print('mcast ok')" ``` Нюансы host-режима: - backend (`uvicorn`) слушает только `127.0.0.1:8000` — API наружу светится только через nginx на 80. - `postgres` публикуется на `127.0.0.1:5432` (в LAN не торчит); `DB_HOST=127.0.0.1` в `docker-compose.release.yml`. - Устройства должны быть в одном L2-сегменте с VM (mDNS не ходит через маршруты). - Если на VM работает `avahi-daemon`, он держит порт 5353 — при конфликте: `sudo systemctl stop avahi-daemon`. Синхронизация значений БД: имя/пользователь/пароль в корневом `.env` (`DB_NAME`, `DB_USER`, `DB_PASSWORD`) должны совпадать с `env_config/.env`. При чистой установке `ENCRYPTION_KEY` можно оставить пустым (сгенерируется и сохранится сам); при переносе существующей БД — ключ должен совпадать со старым, иначе пароли камер расшифровать не удастся. ### Запуск на Windows/Docker Desktop > ВНИМАНИЕ: `docker-compose.release.yml` — host-режим (`network_mode: host`) и рассчитан на Linux-VM. > На Docker Desktop (WSL2) host-сеть — это сеть WSL2-VM, multicast до LAN Windows она не отдаёт. > Для локальной разработки на Windows используйте `docker-compose.yml` (bridge-режим). ```powershell Copy-Item .env.example .env # положить env_config/.env, скопировать docker-compose.release.yml и nginx.host.conf docker compose -f docker-compose.release.yml pull docker compose -f docker-compose.release.yml up -d ``` По умолчанию образы берутся как `sazanof/umni-ecosystem-*:latest`. Другой аккаунт/версию задайте переменными окружения (`IMAGE_OWNER`, `IMAGE_TAG`) — см. шапку `docker-compose.release.yml`. ### Обновление и бэкап Команда: ```powershell docker compose -f docker-compose.release.yml pull docker compose -f docker-compose.release.yml up -d ``` Данные БД переживают обновление (том `postgres_data`); бэкап БД — `pg_dump`. Хранилища на хосте подключаются маунтами — подробнее в [DOCKER.md](DOCKER.md#хранилища-хостовые-пути-в-docker).