SSD Nodes Learn 🎉 VPS от $4.99/мес
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-08

Как развернуть Octop на своем VPS через Docker Compose

Пошаговое руководство по установке Octop версии v0.9.19. Настройте изоляцию пользователей, TLS и OpenAI-совместимый бэкенд. Узнайте, почему лучше избегать curl-инсталлятора.

Что такое Octop и зачем его размещать на собственном сервере

Octop — это AI-ассистент для домашнего использования или небольшой команды, который вы размещаете на своем оборудовании. Причина предпочесть Octop обычному чат-интерфейсу заключается в изоляции пользователей друг от друга. Open WebUI предоставляет браузерный интерфейс для работы с моделью. Octop добавляет систему учетных записей с ролью администратора, личное рабочее пространство и набор учетных данных для каждого пользователя, а также библиотеку специализированных агентов, между которыми пользователь может переключаться в зависимости от задачи. Именно это отличие позволяет одному VPS обслуживать пять человек вместо одного.

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

Важный момент, который стоит прояснить, прежде чем тратить вечер на настройку. Octop — это программное обеспечение версии до 1.0, опубликованное организацией-разработчиком на GitHub, имеющее около 900 звезд по состоянию на август 2026 года. Проект активно развивается, о чем говорят номера версий, и ничто из описанного здесь не является гарантией стабильного пути обновления. Фиксируйте версию (tag), читайте журнал изменений и делайте резервные копии.

Что необходимо перед началом работы

  • VPS под управлением Ubuntu 24.04 с установленными Docker Engine и плагином Compose. Если вы не знакомы с Compose, начните с основ Docker Compose для VPS.
  • git, так как вы будете клонировать конкретный релиз, а не скачивать готовый образ.
  • Доменное имя, указывающее на ваш VPS, так как вам потребуется TLS (transport layer security) перед приложением.
  • Бэкенд модели, поддерживающий API OpenAI: локальный Ollama, self-hosted шлюз или платный ключ доступа.

Сам по себе Octop потребляет мало ресурсов. Это Python-процесс и файл SQLite. Основная нагрузка ложится на бэкенд модели, поэтому, если вы планируете запускать модель на том же сервере, подбирайте конфигурацию оборудования исходя из требований модели.

Почему мы не рекомендуем установщик через curl

В README первым делом предлагается установка одной командой:

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

Мы не рекомендуем использовать этот способ на сервере, который вам дорог, по одной конкретной причине: этот скрипт отсутствует в репозитории. Он отдается из бакета Tencent Cloud Object Storage. Никакие действия с ним не фиксируются git-тегами или коммитами, поэтому вы не сможете сравнить сегодняшний скрипт с прошлонедельным, а история изменений отсутствует. Бакет может завтра отдать другие байты, и в проекте не останется никаких записей об этом. Передача результата напрямую в 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

По состоянию на август 2026 года опубликованных образов для загрузки нет. Поставляемый файл Compose собирает образ из репозитория, поэтому фиксация версии означает переключение на соответствующий git-тег.

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 — это имя, которое получает ваша собственная сборка, а не ссылка на реестр, поэтому 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 загружает при старте. В руководстве по файлам окружения и секретам в Docker Compose подробно объясняется, почему эти два механизма не являются идентичными.

Соберите и запустите сервис:

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, прежде чем открывать браузер.

Теперь присвойте только что собранному образу осмысленное имя, так как следующая команда --build перезапишет octop:latest, и вы не сможете их различить:

docker image tag octop:latest octop:0.9.19

При первом запуске выполняется octop init, и начальные учетные данные записываются в том с данными:

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

Значения по умолчанию — admin / octop, и они применяются только при первой инициализации. Именно в этом кроется причина вопроса, который задают постоянно: изменение OCTOP_DEFAULT_PASSWORD после того, как контейнер уже был запущен хотя бы раз, ничего не меняет, так как учетная запись уже существует. Измените пароль через панель управления.

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

Строка ports: выше привязывает контейнер ко всем сетевым интерфейсам VPS. В момент запуска контейнера панель управления оказывается доступна из публичного интернета в открытом виде, причём с паролем по умолчанию. Значение по умолчанию 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}"

Не пытайтесь исправить это с помощью обычного файла переопределения. Compose объединяет списки ports из нескольких файлов, а не заменяет их, поэтому в итоге вы получите публикацию обоих портов, и второй не сможет привязаться. Если вы хотите оставить исходный файл без изменений, используйте тег !override для этой последовательности — это документированный способ замены, а не добавления. В пояснении о том, как Compose объединяет несколько файлов описаны остальные правила слияния.

Привязка к loopback также решает проблему, с которой вы иначе столкнулись бы при настройке межсетевого экрана. 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: панель управления загружается нормально, но каждое отправленное сообщение зависает без ошибок на странице. Параметр proxy_buffering off важен, так как эндпоинт для возобновления работы с участием человека возвращает text/event-stream, а SSE (server-sent events), удерживаемые в буфере прокси, приходят одним блоком в конце вместо потоковой передачи. Параметр proxy_read_timeout необходим для длительных запусков инструментов, так как стандартный таймаут в 60 секунд прерывает работу агента в процессе выполнения и записывает в лог upstream timed out (110: Connection timed out).

Как работает аутентификация JWT за прокси

Octop выполняет аутентификацию с помощью bearer-токена, а не 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 передает токен в URL. Эндпоинт имеет вид WS /agents/{id}/chat/ws?token=<jwt>, так как JavaScript в браузере не может установить заголовок Authorization при рукопожатии WebSocket. TLS защищает этот токен при передаче. Однако он не защищает его от ваших собственных логов: Nginx по умолчанию записывает полную строку запроса, включая строку параметров, в access_log, поэтому рабочий токен реального пользователя попадает в текстовый файл на сервере. Логируйте путь без аргументов. $uri — это нормализованный путь с уже удаленной строкой параметров, поэтому поместите его в блок http и ссылайтесь на него из конфигурации сервера:

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, поэтому токен остается действительным в течение 24 часов после входа. Единственный документированный способ аннулировать токен — это octop admin rotate-jwt-secret, который обновляет ключ подписи, хранящийся в ~/.octop/secrets/jwt_secret, и немедленно делает недействительными все существующие токены для всех пользователей. Поэтому, когда кто-то покидает команду, порядок действий следующий: удалить пользователя, обновить секретный ключ, а затем попросить остальных пользователей войти в систему снова. Если это кажется слишком сложным, сократите время жизни токена, не забыв добавить переменную в список environment:, а также в .env:

OCTOP_ACCESS_TOKEN_TTL=28800

Защита от перебора реализована: OCTOP_LOGIN_MAX_ATTEMPTS по умолчанию составляет 5 попыток, а OCTOP_LOGIN_LOCKOUT_SECONDS — 900 секунд, поэтому заблокированный пользователь просто ждет пятнадцать минут, вместо того чтобы видеть нерабочую установку. Octop имеет собственное хранилище пользователей и не поддерживает OIDC в версии v0.9.19, поэтому, если вам нужен полноценный single sign-on, установите перед ним аутентифицирующий прокси, для чего предназначен самостоятельно развернутый сервер Authentik.

Настройка Octop для работы с модельным бэкендом

Провайдеры настраиваются для каждого агента в панели управления, а octop provider list показывает текущие параметры. Octop поставляется с предустановками для API, совместимых с OpenAI, DashScope (Qwen) и Ollama. Учетные данные хранятся в таблице providers вашей собственной базы данных SQLite. Выбор провайдера определяет стоимость использования и то, какие данные покидают сервер.

Локальная модель через Ollama. Данные не покидают сервер, а платой за использование становится оперативная память, а не токены. Важный нюанс: контейнер не может обратиться к Ollama на хосте через 127.0.0.1:11434, так как этот адрес является loopback-интерфейсом самого контейнера. Добавьте запись host gateway в сервис:

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

Затем установите базовый URL провайдера на http://host.docker.internal:11434/v1 — это путь Ollama, совместимый с OpenAI. В поле API key введите любую непустую строку: Ollama игнорирует это поле, но клиенты OpenAI не отправляют запросы с пустым ключом. Чтобы это заработало, Ollama должна принимать соединения не только через loopback, что требует настройки OLLAMA_HOST=0.0.0.0:11434 в юните systemd. Это небезопасная часть: у Ollama нет встроенной аутентификации, поэтому открытый порт 11434 на публичном IP-адресе делает ваш сервер доступным для любого, кто его просканирует. Разрешите доступ только из частной подсети Docker sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp, а остальные соединения блокируйте. В запуске Ollama на VPS описан подбор размера моделей, а в сравнении Ollama и vLLM — случаи, когда Ollama перестает быть оптимальным решением.

Еще одно предупреждение касательно локальных моделей: проблема, которая выглядит как ошибка в Octop, таковой не является. Агенты работают через вызов инструментов, поэтому системный промпт, определения инструментов и история переписки формируют большой объем данных. Ollama по умолчанию использует небольшое окно контекста, из-за чего начало промпта, где находятся определения инструментов, выпадает из памяти. В результате модель перестает вызывать инструменты или начинает выдумывать несуществующие. Увеличьте num_ctx до 16k или 32k и выберите модель, которая эффективно работает с вызовом функций (function calling).

Self-hosted шлюз. Установите self-hosted шлюз LiteLLM между Octop и остальными сервисами. Вы получите единый базовый URL, отдельные ключи для каждого пользователя, лимиты расходов и централизованное логирование. Вы также сможете менять модель на бэкенде, не внося изменений в настройки Octop.

Платный API. Обеспечивает наилучшее качество, но требует компромисса: содержимое диалогов покидает ваш сервер и передается провайдеру, что противоречит основной цели self-hosting. Ключ вводится в docker/.env как OPENAI_API_KEY, этот параметр уже проброшен в Compose-файл.

Что бы вы ни выбрали, Compose-файл также содержит переменные OCTOP_LANGFUSE_ENABLED, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY и LANGFUSE_BASE_URL. Это позволяет отправлять трассировки в ваш собственный экземпляр Langfuse и видеть реальные действия агентов, а не пытаться угадать их по окну чата.

Пользователи, роли и общая библиотека агентов

Учетная запись администратора, созданная при первой загрузке, управляет остальными пользователями. Каждый пользователь получает собственные агенты, рабочее пространство и учетные данные; эта изоляция обеспечивается токеном, который хранится в браузере. Параллельно существует общий пул навыков и вспомогательных агентов, доступных всем пользователям. Именно эта функция делает использование системы оправданным для семьи: один человек создает эффективного агента для поиска, и остальным не нужно повторять эту работу.

Будьте осторожны с инструментами. Octop поддерживает подтверждение использования инструментов и защитные механизмы для команд оболочки. Оба этих средства работают, однако агент, выполняющий команды shell, запускает их внутри контейнера Octop, к которому подключен ваш том с данными. Защитные механизмы ограничивают последствия неосторожных запросов. Они не являются полноценной «песочницей», поэтому оставляйте подтверждение использования инструментов включенным для всех, кому вы не доверили бы прямой доступ к командной строке. Если вы выбираете между различными вариантами, в обзоре 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 августа 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. Если что-то пойдет не так, возврат к старому тегу и пересборка восстановят код, но только архив с данными позволит вернуть базу данных в исходное состояние.

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

Типовые сбои и сообщения об ошибках

Проверка работоспособности (health check) не отвечает. 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?

Только если вам нужны дополнительные функции. Open WebUI — это чат-интерфейс для работы с моделью, который отлично справляется со своей задачей для одного пользователя или доверенной группы лиц. Octop добавляет систему учётных записей с ролью администратора, рабочие пространства и учётные данные для каждого пользователя, а также библиотеку специализированных агентов. Это позволяет нескольким людям использовать один сервер, не смешивая историю переписки. Если вам достаточно одной учётной записи, Open WebUI будет более простым и зрелым решением.

Почему не стоит использовать скрипт установки Octop через curl?

Скрипт загружается из хранилища Tencent Cloud Object Storage, а не из репозитория, поэтому он не привязан к git-тегам или коммитам. Вы не сможете сравнить текущую версию скрипта с той, что была неделю назад, а передача его конвейером в bash запускает выполнение кода до того, как вы его прочитаете. Кроме того, скрипт устанавливает собственное окружение Python 3.12 непосредственно в хост-систему, в обход вашего пакетного менеджера. Сначала скачайте и изучите скрипт или разверните приложение через Docker Compose, используя проверенный тег.

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

Да. Octop поддерживает API, совместимые с OpenAI, и включает предустановку для 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?

Вам необходим прокси. Файл Compose, поставляемый с Octop, публикует порт 8088 на всех интерфейсах без TLS, поэтому пароли и bearer-токены будут передаваться через интернет в открытом виде. Измените публикуемый порт на 127.0.0.1:8088:8088 и установите перед приложением Caddy или nginx с сертификатом. При использовании nginx настройте пересылку заголовков WebSocket upgrade и установите proxy_buffering off, иначе страница загрузится, но чат не будет отвечать.

Готов ли Octop к промышленной эксплуатации?

Проект находится на стадии до версии 1.0, и по состоянию на август 2026 года выпускается несколько релизов в неделю, поэтому его следует рассматривать как перспективный, но не устоявшийся продукт. Это приемлемо для семьи или небольшой внутренней команды, если вы фиксируете конкретный тег, изучаете журнал коммитов перед каждым обновлением и создаёте резервную копию тома с данными перед каждой пересборкой. Не запускайте его на latest и пока не храните в нём данные клиентов.