SSD Nodes Learn Hosting plans →
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-28

Як розгорнути Octop на VPS для кількох користувачів

Налаштуйте Octop v0.9.19 через Docker Compose з фіксованим tag: ізоляція користувачів, OpenAI-сумісний backend, TLS і причина не використовувати curl installer.

Що таке Octop і навіщо розгортати його на власному сервері

Octop — це self-hosted AI-асистент для родини або невеликої команди. Причина розгорнути Octop самостійно, а не використовувати звичайний чат-інтерфейс, полягає в ізоляції користувачів один від одного. Open WebUI надає браузерний інтерфейс для взаємодії з моделлю. Octop додає облікові записи з роллю адміністратора, приватний робочий простір і набір облікових даних для кожного користувача, а також бібліотеку спеціалізованих агентів, між якими користувач може перемикатися залежно від завдання. Завдяки цьому один VPS може обслуговувати п’ятьох людей, а не лише одного.

Проєкт розміщено на github.com/TencentCloud/Octop. Це один процес, який обслуговує вебпанель, інтерфейс командного рядка, канали чатів (Feishu, DingTalk, QQ, Discord, WeCom) і заплановані завдання. Усі вони використовують одну базу даних SQLite у ~/.octop/. Усе нижче описано для tag v0.9.19, випущеного 5 August 2026. Якщо ви ще обираєте платформу, у порівнянні альтернатив Open WebUI, які можна запустити на VPS розглянуто ширший вибір.

Перед тим як витрачати на це цілий вечір, варто чітко усвідомити один момент. Octop — це програмне забезпечення до версії 1.0, опубліковане в GitHub-організації постачальника; станом на August 2026 воно має приблизно 900 зірок. Проєкт швидко розвивається, що видно з номерів версій, тому наведені інструкції не гарантують стабільного шляху оновлення. Зафіксуйте tag, прочитайте журнал змін і зберігайте резервні копії.

Що потрібно підготувати перед початком

  • VPS з Ubuntu 24.04, Docker Engine і Compose plugin. Якщо ви ще не працювали з Compose, почніть із матеріалу Основи Docker Compose для VPS.
  • git, оскільки ви перевірятимете release tag, а не завантажуватимете image.
  • Доменне ім’я, що вказує на VPS, оскільки перед сервісом потрібно налаштувати TLS (transport layer security).
  • Model backend із підтримкою OpenAI API: локальний Ollama, self-hosted gateway або платний ключ.

Сам Octop споживає мало ресурсів. Це Python-процес і файл SQLite. Основне навантаження створює model backend. Тому, якщо ви плануєте запускати model на тому самому сервері, виберіть розмір сервера відповідно до вимог model.

Чому ми не рекомендуємо інсталятор через curl

У README спочатку наведено однорядкову команду встановлення:

curl -fsSL https://finnie-1258344699.cos.ap-guangzhou.myqcloud.com/octop/install.sh | bash

Ми не рекомендуємо використовувати її на сервері, який для вас важливий, з однієї конкретної причини: цей скрипт не входить до репозиторію. Він розміщується у сховищі Tencent Cloud Object Storage. На нього не поширюється ні git tag, ні commit, тому ви не можете порівняти сьогоднішню версію скрипту з версією минулого тижня. Також немає історії, яка пояснює внесені зміни. Завтра bucket може повернути інший вміст, і в проєкті це ніяк не буде зафіксовано. Передавання результату безпосередньо до bash також означає, що машина запустить скрипт до того, як ви прочитаєте хоча б один його рядок.

Інсталятор також записує файли безпосередньо на хост, а не в контейнер. Він використовує uv, щоб завантажити Python 3.12 і створити середовище, про яке ваш пакетний менеджер нічого не знає. Тому згодом видаляти це середовище доведеться вручну.

Є два кращі варіанти. Завантажте скрипт, прочитайте його, а потім запустіть. Це займе тридцять секунд: curl -fsSL <url> -o install.sh, потім less install.sh, потім bash install.sh. Або використовуйте Docker — саме цьому присвячено решту цього посібника. Пакет PyPI (pip install octop) принаймні є артефактом із версією, який можна прив’язати до певного релізу.

Розгортання Octop за допомогою Docker Compose із фіксацією на v0.9.19

Станом на August 2026 опублікованого image для завантаження немає. Файл Compose, що постачається з проєктом, збирає image з репозиторію, тому для фіксації версії потрібно перейти на відповідний git tag. Це на один крок більше, ніж вимагає більшість self-hosted проєктів. Наприклад, self-hosted робочий простір AFFiNE фіксує опублікований tag image і нічого не збирає на вашому VPS. Наведена нижче процедура клонування, переходу на tag і складання така сама, як у посібнику з розгортання openGym. Якщо ви вже виконували її один раз, то знаєте її структуру.

git clone https://github.com/TencentCloud/Octop.git
cd Octop
git checkout v0.9.19

Ось сервіс, який визначає цей файл. Тут залишено лише важливі частини:

services:
  octop:
    build:
      context: ..
      dockerfile: docker/Dockerfile
    image: octop:latest
    container_name: octop
    restart: unless-stopped
    ports:
      - "${OCTOP_PORT:-8088}:${OCTOP_PORT:-8088}"
    volumes:
      - ${OCTOP_DATA:-~/.octop}:/data/.octop
    environment:
      - HOME=/data
      - OCTOP_BIND_HOST=0.0.0.0
      - OCTOP_PORT=${OCTOP_PORT:-8088}
      - OCTOP_DEFAULT_PASSWORD=${OCTOP_DEFAULT_PASSWORD:-octop}
      - OCTOP_ADMIN_USERNAME=${OCTOP_ADMIN_USERNAME:-admin}
      - OPENAI_API_KEY=${OPENAI_API_KEY:-}

Зверніть увагу на блок build:. image: octop:latest — це ім’я вашого власного build, а не посилання на registry. Тому latest тут означає те, що ви скомпілювали останнім. Укажіть явний шлях до даних, а не залишайте значення за замовчуванням. До першого запуску задайте реальний пароль облікового запису адміністратора. Додайте це до docker/.env:

OCTOP_PORT=8088
OCTOP_ADMIN_USERNAME=admin
OCTOP_DEFAULT_PASSWORD=<a long random password>
OCTOP_DATA=/srv/octop-data

Тут є важливий нюанс, який стосується всього іншого файлу. Compose читає docker/.env лише для підстановки заповнювачів ${...} у YAML. Ключ, доданий до цього файлу, не передається в контейнер, якщо його також не вказано в environment: у файлі Compose. Якщо додати OCTOP_ACCESS_TOKEN_TTL лише до .env, це взагалі нічого не зробить, і помилки не буде. Альтернативний варіант — записати ті самі ключі до ~/.octop/env у змонтованому каталозі даних. Octop завантажує цей файл під час запуску. У посібнику з env-файлів і секретів у Docker Compose пояснено, чому ці два механізми не є взаємозамінними.

Зберіть image і запустіть його:

docker compose -f docker/docker-compose.yml up -d --build
docker compose -f docker/docker-compose.yml ps
curl http://127.0.0.1:8088/api/health

Працюючий екземпляр повертає під час health check значення {"status":"ok","version":"..."}. Якщо повертається будь-що інше, перед перевіркою в браузері прочитайте docker compose -f docker/docker-compose.yml logs -f octop.

Тепер надайте щойно зібраному image зрозуміле ім’я. Наступний --build перезапише octop:latest, і ви не зможете відрізнити ці два image:

docker image tag octop:latest octop:0.9.19

Під час першого запуску виконується octop init, а початкові облікові дані записуються до data volume:

docker exec -it octop cat /data/.octop/credential.txt

Значення за замовчуванням — admin / octop. Вони застосовуються лише під час першої ініціалізації. Саме тому часто запитують: зміна OCTOP_DEFAULT_PASSWORD після першого запуску контейнера нічого не змінює, оскільки обліковий запис уже створено. Змініть пароль у dashboard.

Не публікуйте порт 8088

Рядок ports: вище прив’язує порт до всіх інтерфейсів VPS. Щойно контейнер запускається, dashboard стає доступним із публічної мережі у відкритому вигляді, зі стандартним паролем. Власне значення OCTOP_BIND_HOST за замовчуванням для Octop — 127.0.0.1; файл Compose змінює його на 0.0.0.0, оскільки процес має приймати трафік з-поза власного мережевого простору імен. Ця зміна правильна. Проблема саме в опублікованому порту, який відкриває доступ до сервісу.

Змініть рядок ports: у docker/docker-compose.yml, щоб прив’язка прослуховувала лише loopback:

    ports:
      - "127.0.0.1:${OCTOP_PORT:-8088}:${OCTOP_PORT:-8088}"

Не намагайтеся виправити це звичайним override-файлом. Compose об’єднує списки ports з кількох файлів, а не замінює їх. У результаті буде опубліковано обидві прив’язки, і друга не зможе прив’язатися до порту. Якщо потрібно залишити upstream-файл без змін, використайте тег !override для послідовності. Це задокументований спосіб замінити елементи замість їх додавання. Пояснення об’єднання кількох файлів Compose містить решту правил такого об’єднання.

Прив’язка до loopback також усуває проблему, яка інакше виникла б із firewall. Docker записує правила опублікованих портів у таблицю nat перед ланцюжками, якими керує ufw, тому ufw deny 8088 не блокує порт опублікованого контейнера. Порт, прив’язаний до 127.0.0.1, недоступний ззовні незалежно від налаштувань ufw. Саме тому це правильне рішення, а не запасний варіант.

Налаштуйте TLS перед reverse proxy

Caddy — найкоротший шлях, оскільки він самостійно запитує сертифікат через ACME (automatic certificate management environment) і проксує WebSockets без додаткових налаштувань:

octop.example.com {
    reverse_proxy 127.0.0.1:8088
}

nginx потребує більш ретельного налаштування, оскільки Octop передає чат через WebSocket:

server {
    listen 443 ssl;
    server_name octop.example.com;

    ssl_certificate     /etc/letsencrypt/live/octop.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/octop.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8088;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

Кожен рядок виконує певну функцію. Чат працює через WS /agents/{id}/chat/ws, тому без proxy_http_version 1.1 і двох заголовків upgrade nginx відповідає на спробу оновлення кодом 400 Bad Request: dashboard завантажується нормально, а кожне надіслане повідомлення зависає назавжди без помилки на сторінці. proxy_buffering off важливий, оскільки endpoint відновлення human-in-the-loop повертає text/event-stream, а SSE (server-sent events), що зберігаються в буфері proxy, надходять одним блоком наприкінці замість потокової передачі. proxy_read_timeout потрібен для тривалих запусків інструментів, оскільки стандартне значення 60 секунд перериває роботу агента посеред виконання завдання, а в журналах з’являється upstream timed out (110: Connection timed out).

Як працює JWT-автентифікація за reverse proxy

Octop автентифікує запити за bearer token, а не за cookie. POST /api/auth/login повертає {access_token, role, user, ...}, а наступні запити містять Authorization: Bearer <access_token>. Для reverse proxy це добре: не потрібно налаштовувати домен cookie, прапорець Secure або правило SameSite, тому сесія, яка працювала на http://127.0.0.1:8088, так само працює на https://octop.example.com.

Перед підключенням реальних користувачів потрібно врахувати два наслідки.

WebSocket передає token у URL. Endpoint має вигляд WS /agents/{id}/chat/ws?token=<jwt>, оскільки JavaScript у браузері не може встановити заголовок Authorization під час WebSocket handshake. TLS захищає цей token під час передавання. Але він не захищає token від ваших власних журналів: nginx за замовчуванням записує повний рядок запиту разом із query string у access_log, тому робочий token реального користувача опиняється у звичайному текстовому файлі на сервері. Записуйте шлях без аргументів. $uri — це нормалізований шлях, з якого query string уже вилучено. Додайте цей параметр до блоку http і підключіть його в server:

log_format octop_noargs '$remote_addr [$time_local] '
                        '"$request_method $uri $server_protocol" '
                        '$status $body_bytes_sent';
access_log /var/log/nginx/octop.log octop_noargs;

Окремого виходу із сесії немає. OCTOP_ACCESS_TOKEN_TTL за замовчуванням має значення 86400, тому token залишається дійсним протягом 24 годин після входу. Єдиний документований спосіб інвалідувати один token — octop admin rotate-jwt-secret. Він змінює signing key, збережений у ~/.octop/secrets/jwt_secret, і негайно інвалідує всі активні token для всіх користувачів. Тому після звільнення учасника команди порядок дій такий: видаліть користувача, змініть secret, а потім попросіть решту користувачів увійти знову. Якщо це надто жорсткий варіант, скоротіть час життя token. Також додайте змінну до списку environment: і до .env:

OCTOP_ACCESS_TOKEN_TTL=28800

Захист від brute force уже передбачено: OCTOP_LOGIN_MAX_ATTEMPTS за замовчуванням дорівнює 5 невдалим спробам, а OCTOP_LOGIN_LOCKOUT_SECONDS — 900. Тому заблокований користувач просто чекає п’ятнадцять хвилин, а не вважає інсталяцію несправною. Octop має власне сховище користувачів і не має документованої підтримки OIDC у версії v0.9.19. Якщо потрібен повноцінний single sign-on, розмістіть перед ним authenticating proxy. Саме для цього підходить self-hosted сервер Authentik.

Налаштуйте Octop на модельний бекенд

Провайдерів налаштовують для кожного агента в dashboard, а octop provider list показує поточні значення. Octop постачається з готовими налаштуваннями для OpenAI-compatible API, DashScope (Qwen) і Ollama. Облікові дані зберігаються в таблиці providers вашої власної SQLite database. Вибір провайдера визначає витрати та те, які дані залишають сервер.

Локальна модель з Ollama. Дані не залишають сервер, а замість токенів ви витрачаєте RAM. Важлива деталь мережевого підключення: контейнер не може звернутися до Ollama на хості через 127.0.0.1:11434, оскільки ця адреса вказує на loopback самого контейнера. Додайте до сервісу запис про gateway хоста:

    extra_hosts:
      - "host.docker.internal:host-gateway"

Потім задайте базову URL провайдера як http://host.docker.internal:11434/v1. Це OpenAI-compatible path для Ollama. У поле API key введіть будь-який непорожній рядок, оскільки Ollama його ігнорує, але OpenAI clients не надсилають порожній ключ. Ollama також має приймати з’єднання не лише з loopback. Для цього в його systemd unit потрібен параметр OLLAMA_HOST=0.0.0.0:11434. Це небезпечна частина: Ollama не має authentication, тому відкритий порт 11434 на публічній IP-адресі перетворює сервер моделей на доступний для будь-кого, хто першим його просканує. Дозвольте доступ лише з приватного діапазону Docker, sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp, а решту забороніть. У матеріалі Запуск Ollama на VPS описано вибір розміру моделі, а в матеріалі порівняння Ollama та vLLM пояснено, коли Ollama перестає бути правильним сервером.

Є ще одне застереження щодо локальних моделей. Воно схоже на помилку в Octop, але нею не є. Агенти працюють через виклик tools. System prompt, визначення tools і history разом утворюють великий prompt. Ollama обслуговує моделі з помірним default context window, тому початок prompt, де містяться визначення tools, виходить за межі вікна. Після цього модель перестає викликати tools або вигадує неіснуючі tools. Збільште num_ctx до 16k або 32k і виберіть модель, яка справді добре підтримує function calling. Відповідь, що обривається посеред речення, має іншу причину й пов’язана з іншим параметром — num_predict. Якщо відповіді повертаються обрізаними, варто перевірити, де задано num_predict і що означає done_reason, перш ніж звинувачувати агента. Якщо ви хочете одразу почати з конкретного кандидата, а не зі списку, спробуйте Nemotron 3.5 Lightning. У цьому матеріалі наведено точний tag для завантаження, потрібний обсяг RAM і дані про продуктивність у режимі лише CPU.

Self-hosted gateway. Розмістіть self-hosted LiteLLM gateway між Octop та всіма іншими компонентами. Ви отримаєте одну базову URL, окремий ключ для кожного користувача, ліміти витрат і єдиний журнал. Модель за gateway також можна замінити без змін у Octop.

Платний API. Це найкраща якість, але з очевидним компромісом: вміст розмов залишає ваш сервер і надходить до провайдера. Це суперечить головній меті self-hosting. Ключ потрібно вказати в docker/.env як OPENAI_API_KEY. Compose file вже передає це значення далі.

Незалежно від вибору, Compose file також містить OCTOP_LANGFUSE_ENABLED, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY і LANGFUSE_BASE_URL. Тому ви можете надсилати traces до власного екземпляра Langfuse і бачити, що саме роблять агенти, замість того щоб робити висновки лише з chat window.

Користувачі, ролі та спільна бібліотека агентів

Обліковий запис адміністратора, створений під час першого запуску, створює та керує іншими обліковими записами. Кожен користувач має власних агентів, робочий простір і облікові дані. Ізоляцію забезпечує токен, який зберігається в браузері. Окремо є спільний пул навичок і субагентів, доступний усім користувачам. Саме це робить рішення корисним для сім’ї: один користувач один раз створює якісного агента для досліджень, і решті не потрібно створювати його повторно.

Будьте обережні з інструментами. Octop підтримує підтвердження використання інструментів і обмеження для shell-команд, і обидві функції працюють. Проте агент, який виконує shell-команди, виконує їх усередині контейнера Octop, де змонтовано ваш том із даними. Обмеження зменшують шкоду, яку може спричинити необережний prompt. Вони не є межею sandbox, тому залиште підтвердження використання інструментів увімкненим для користувачів, яким ви не надали б доступ до shell. Якщо ви порівнюєте це рішення з іншими варіантами, огляд self-hosted AI-агентів порівнює підхід кожного з них до цього питання.

Оновлення проєкту, який випускає релізи з такою швидкістю

ChartDays between Octop releases, v0.9.16 to v0.9.19 (repository tags, 7 August 2026)
The data behind this chart
[
  {
    "version": "v0.9.16",
    "days_since_previous_release": 2
  },
  {
    "version": "v0.9.17",
    "days_since_previous_release": 3
  },
  {
    "version": "v0.9.18",
    "days_since_previous_release": 1
  },
  {
    "version": "v0.9.19",
    "days_since_previous_release": 3
  }
]

Це дати тегів із репозиторію станом на 7 August 2026. За дев’ять днів вийшло 4 позначених релізів. Інтервал між релізами становив лише 1 день, а v0.9.19 вийшов через 3 днів після попереднього тегу. Така частота релізів свідчить, що проєкт активно розвивається, але це не причина запускати latest. Перед оновленням ознайомтеся зі змінами:

cd Octop
git fetch --tags
git tag --sort=-creatordate | head
NEW_TAG=$(git tag --sort=-creatordate | head -1)
git log --oneline "v0.9.19..$NEW_TAG"

Щоразу спочатку створюйте резервну копію, оскільки міграції бази даних виконуються під час запуску, а невдала міграція у проєкті до версії 1.0 — це проблема, яку доведеться вирішувати вам:

docker compose -f docker/docker-compose.yml stop
sudo tar czf octop-backup-$(date +%F).tgz -C /srv octop-data
docker compose -f docker/docker-compose.yml start

Потім перемкніться на новий тег і перебудуйте проєкт за допомогою docker compose -f docker/docker-compose.yml up -d --build. Якщо щось піде не так, перемикання на старий тег і повторна збірка відновлять код. Однак базу даних можна відновити лише з tarball.

У цьому tarball містяться octop.db, config.json, секрет підпису JWT і credential.txt, тому він має такий самий рівень чутливості, як і сам сервер. Встановіть для нього режим 600 і зберігайте копію поза сервером. Для більших інсталяцій проєкт також постачає docker/docker-compose.postgres.yml, який запускає PostgreSQL із pgvector замість SQLite.

Типові причини помилок і повідомлення, які ви побачите

Перевірка працездатності не відповідає. curl http://127.0.0.1:8088/api/health зависає або відмовляє в підключенні. Перегляньте docker compose -f docker/docker-compose.yml logs -f octop. Контейнер, який завершує роботу під час першої ініціалізації, зазвичай не може записати дані до каталогу даних. Перевірте власника каталогу, який ви вказали в OCTOP_DATA.

Панель керування завантажується, але чат зависає. На сторінці немає помилки, але відповідь не надходить. Відкрийте консоль браузера та перевірте, чи не завершується помилкою підключення до wss://octop.example.com/agents/.../chat/ws. Проксі не передає upgrade-запит. Додайте заголовки proxy_http_version 1.1, Upgrade і Connection.

Вся відповідь з’являється одночасно із затримкою в кілька секунд. Потокова передача працює, але буферизацію увімкнено. Задайте proxy_buffering off.

bind: address already in use. Порт 8088 уже зайнятий іншим процесом. sudo ss -tlnp | grep 8088 покаже, який саме процес його використовує. Також це трапляється, якщо у файлі перевизначень ви додали другий запис ports замість редагування початкового.

Правильний пароль відхиляється. П’ять невдалих спроб активують блокування на 900 секунд. Дочекайтеся завершення блокування, а не перевстановлюйте застосунок.

Новий пароль у .env не подіяв. Ці облікові дані застосовуються лише під час першої ініціалізації. Змініть пароль у панелі керування.

Агент відповідає, але ніколи не запускає інструмент. Майже завжди проблема пов’язана з локальною моделлю: вікно контексту замале для описів інструментів або модель погано підтримує виклик функцій. Збільште num_ctx і спробуйте модель, призначену для роботи з інструментами.

FAQ

Чи є Octop заміною Open WebUI?

Лише якщо вам потрібні додаткові можливості Octop. Open WebUI — це чат-інтерфейс перед моделлю, і він добре виконує це завдання для однієї людини або сім’ї, якій можна довіряти. Octop додає облікові записи з роллю адміністратора, окремі робочі простори й облікові дані для кожного користувача, а також змінювану бібліотеку спеціалізованих агентів. Тому кілька людей можуть спільно використовувати один сервер, не маючи спільної історії. Якщо вам достатньо одного облікового запису, Open WebUI буде простішим і значно зрілішим вибором.

Чому не слід використовувати скрипт інсталяції Octop через curl?

Скрипт розміщено у сховищі Tencent Cloud Object Storage, а не в репозиторії, тому на нього не поширюється жоден git tag або commit. Ви не можете порівняти його поточну поведінку з поведінкою минулого тижня, а передавання скрипту через pipe до bash запускає його ще до того, як ви його прочитаєте. Скрипт також встановлює Octop безпосередньо на хост у власне середовище Python 3.12, поза межами вашого менеджера пакетів. Завантажте скрипт і спочатку прочитайте його або розгорніть Octop за допомогою Docker Compose з перевіреного tag.

Чи може Octop використовувати локальну модель замість платного API?

Так. Octop підтримує API, сумісні з OpenAI, і постачається з preset для Ollama. Тому підключення до http://host.docker.internal:11434/v1 працює після додавання extra_hosts: ["host.docker.internal:host-gateway"] до контейнера та встановлення OLLAMA_HOST=0.0.0.0:11434 на хості. Обмежте доступ до порту 11434 діапазоном адрес Docker, оскільки Ollama не має власної автентифікації. Збільште значення num_ctx в Ollama до 16k або більше, оскільки промпти агентів із визначеннями інструментів перевищують стандартне контекстне вікно, після чого модель припиняє викликати інструменти.

Чи потрібен reverse proxy, чи можна відкрити порт 8088?

Reverse proxy потрібен. Файл Compose, який постачається з Octop, публікує порт 8088 на всіх інтерфейсах без TLS. Тому паролі та bearer-токени передавалися б через інтернет у відкритому вигляді. Змініть опублікований порт на 127.0.0.1:8088:8088 і розмістіть перед Octop Caddy або nginx із сертифікатом. У nginx передайте заголовки для оновлення WebSocket-з’єднання та встановіть proxy_buffering off. Інакше сторінка завантажиться, але чат мовчки не відповідатиме.

Чи готовий Octop до використання в production?

Octop ще не досяг версії 1.0 і станом на August 2026 випускає кілька позначених tag релізів на тиждень. Тому вважайте його перспективним, але ще нестабільним продуктом. Для сім’ї або невеликої внутрішньої команди це прийнятно, якщо зафіксувати точний tag, перед кожним оновленням переглядати журнал commit і перед кожною перебудовою створювати резервну копію тому з даними. Не запускайте його на latest і поки що не зберігайте в ньому дані клієнтів.