SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-28

Как развернуть open-kritt на VPS через Docker Compose

Руководство по установке open-kritt на удаленный сервер. Инструкция включает настройку Docker Compose, фиксацию версии, проброс порта 5173 через SSH и лимиты бюджета API.

Почему стоит размещать open-kritt на VPS, а не на собственном ноутбуке

Размещайте open-kritt на сервере, который можно удалить и развернуть заново. Инструмент запускает агентов анализа с правами root внутри одноразовых контейнеров, предоставляет каждому из них копию вашего кода с правами на запись и прямой доступ в интернет, а также монтирует Docker socket хоста в свой сервис движка. Это оправданный риск для машины, выделенной под конкретную задачу. Но это плохая идея для устройства, на котором хранятся ваши SSH-ключи.

Этот совет основан на четырех особенностях стандартной настройки, описанных в README и файле compose самого проекта.

Агенты обладают широкими полномочиями. В README указано, что агенты с поддержкой инструментов запускаются от имени root внутри одноразовых контейнеров, имеют доступ к копиям репозиториев с правами на запись и прямой выход в интернет. Это позволяет им устанавливать утилиты, компилировать цели, запускать тесты и создавать прототипы. Сканирование — это не просто линтер, читающий файлы. Это произвольное выполнение кода, которое вы сами инициируете. Доступ в интернет работает в обе стороны: всё, что агент загружает при анализе цели, является недоверенным текстом, попадающим в его промпт. Это тот же риск, что возникает, когда вы предоставляете агенту возможность поиска в сети.

Движок имеет доступ к Docker socket. docker-compose.yml монтирует Docker socket хоста в сервис движка, так как движок создает и запускает по одному контейнеру сканирования для каждой задачи. Любой процесс, имеющий доступ к этому сокету, может запустить контейнер, который примонтирует файловую систему хоста. Таким образом, движок фактически обладает правами root на любом хосте, где он запущен.

Отсутствует экран входа. Бэкенд поставляется без встроенной аутентификации приложения. Доступ к порту означает доступ к результатам ваших проверок и к вашим кредитам у провайдера.

Код, который вы сканируете, часто вам не принадлежит. Направление агентов на сторонний репозиторий означает запуск процесса сборки этого репозитория на вашей машине от имени root и с доступом к сети.

Если вы читали почему агенты для программирования должны работать в одноразовой виртуальной машине, то здесь действует та же модель угроз, только в более жестком варианте. Выделите для open-kritt отдельный VPS, на котором больше ничего нет, и управляйте этим VPS из отдельной учетной записи с минимальными привилегиями, а не от имени root.

Что на самом деле делает open-kritt

open-kritt (репозиторий Kritt-ai/open-kritt, лицензия AGPL-3.0) разбивает исследование уязвимостей на небольшие задачи, выполняет их параллельно с помощью AI-агентов, а затем удаляет дубликаты и ранжирует полученные результаты. Вы определяете рабочий процесс как цепочку специализированных промптов, где каждый этап получает структурированный контекст от предыдущих. Целью сканирования является удаленный или локальный git-репозиторий. Механизмом анализа выступает Codex или Claude Code. После обнаружения кандидата можно запустить дополнительные скрипты для его проверки или создания proof of concept. Проектирование такой цепочки — это стандартная работа с агентами, а не с безопасностью. Поэтому, если промпты, инструменты и передача контекста для вас пока в новинку, изучение принципов работы агентов даст для ваших результатов больше, чем любая настройка из этого руководства.

На выходе вы получаете ранжированный список кандидатов. Рассматривайте его как очередь для триажа, а не как готовый отчет.

Что потребуется перед началом работы

  • VPS под управлением Ubuntu 24.04, Debian 12 или Rocky Linux 9. В документации по установке указано, что именно эти дистрибутивы протестированы для архитектур x86_64 и ARM64.
  • Docker Engine с плагином Compose.
  • Node.js версии 20 или новее на хосте, так как CLI ./kritt запускается на хосте, а не внутри контейнера.
  • Один провайдер моделей: учетная запись Codex или OPENAI_API_KEY, CODEX_API_KEY, ANTHROPIC_API_KEY или OPENROUTER_API_KEY.
  • GITHUB_TOKEN, только если вы планируете сканировать приватные репозитории. В поставляемой документации .env.example это указано прямо: одного токена GitHub недостаточно для выполнения сканирования.

Установка Docker и Node 20

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

Выйдите из системы и войдите снова, чтобы изменения в группах вступили в силу, затем убедитесь в наличии плагина Compose.

docker compose version

Строка версии означает, что Compose установлен как плагин. docker: 'compose' is not a docker command означает, что у вас установлена старая отдельная версия docker-compose, а open-kritt вызывает docker compose. Членство в группе docker равносильно правам root на хосте, поэтому добавляйте в неё только ту учётную запись, под которой работает open-kritt. Подробное руководство по этой настройке см. в запуск Docker на VPS.

В репозиториях Ubuntu 24.04 поставляется Node 18, но CLI завершает работу при использовании версии ниже 20. Используйте NodeSource.

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v

node -v должен вывести v20. или выше. В Rocky Linux 9 аналогичная процедура выполняется через sudo dnf module enable nodejs:20 -y с последующим sudo dnf install -y nodejs.

Клонирование open-kritt и фиксация на помеченном релизе

git clone https://github.com/Kritt-ai/open-kritt
cd open-kritt
git fetch --tags
git tag --list
git checkout v1.3.0

main перемещается вместе с вами. Тег — нет. По состоянию на август 2026 года новейшим тегом является v1.3.0, опубликованный 4 августа 2026 года, а git tag --list показывает состояние репозитория на день клонирования. Переключение на тег оставляет репозиторий в состоянии detached HEAD, что в данном случае является правильным: вы используете этот клон как зафиксированный релиз, а не как ветку для внесения коммитов. Для последующего обновления ознакомьтесь с примечаниями к релизу, выполните git fetch --tags, переключитесь на новый тег и снова запустите ./kritt start, так как start пересобирает образы.

Не запускайте ./kritt с sudo. Документация прямо указывает на это. CLI управляет локальными директориями учетных данных проекта в .data/, поэтому запуск от имени root приведет к тому, что владельцем этих директорий станет root, и последующий обычный запуск не сможет выполнить в них запись.

Настройка доступа к модели с помощью ./kritt setup

./kritt setup

Команда создает .env из .env.example, если файл отсутствует, выводит статус каждого учетного ключа и позволяет задать или удалить их. Команда никогда не выводит значения ключей в терминал. Файлы .env и файл учетных данных движка записываются с правами доступа 0600.

Если вы предпочитаете выполнить настройку вручную:

cp .env.example .env
chmod 600 .env
mkdir -p .data/codex
chmod 700 .data/codex

Затем добавьте ключ провайдера в .env и установите права доступа 0600. В любом случае, рабочие учетные данные провайдера теперь находятся на сервере, что является еще одной причиной не размещать на нем ничего лишнего. Создайте ключ исключительно для этого проекта, чтобы его последующий отзыв не повлиял на другие важные задачи. В разделе Как обезопасить секреты от AI-агентов описаны общие правила работы с конфиденциальными данными.

Установите лимит расходов у провайдера перед первым сканированием

open-kritt спроектирован для параллельного выполнения задач, и именно за этот параллелизм вы платите. Значения по умолчанию в .env.example в версии v1.3.0 консервативны: ENGINE_WORKER_COUNT=2, описанное в файле как осторожный параметр для небольшой машины с 2 vCPU, и ENGINE_MAX_CONCURRENT_SCANS=1. Выше них находятся ENGINE_WORKERS_PER_ACCOUNT=15 — максимальное количество одновременных вызовов корневой модели, разрешенное для одной учетной записи провайдера, и ENGINE_CODEX_MAX_SUBAGENTS_PER_SESSION=5, так как сессия Codex может запускать до пяти дочерних агентов. Увеличьте количество воркеров на более мощном VPS, и число активных вызовов модели вырастет вместе с ним.

В репозитории нет настроек, ограничивающих ваши расходы. В .env.example отсутствует параметр бюджета. Собственные условия остановки движка — это лимиты воркеров плюс ENGINE_HARNESS_TIMEOUT_SECONDS, значение которого по умолчанию составляет 7200 секунд на один запуск harness. Harness здесь — это цикл, который продолжает вызывать модель с инструментами и контекстом, пока что-либо не завершит выполнение, поэтому данный таймаут является ограничением по времени для программы, обернутой вокруг модели, а не лимитом на расходы самой модели. Таким образом, верхний предел должен быть установлен на стороне провайдера. Откройте консоль управления провайдером и установите жесткий ежемесячный лимит до первого сканирования, а не после него. В статье Контроль расходов на AI-агента на VPS подробно описаны настройки для каждого провайдера.

Существует также локальный ограничитель. Установка ENGINE_WORKER_COUNT=0 приостанавливает получение новых заданий, а те же значения воркеров можно изменить на экране настроек после запуска стека.

В этом руководстве не приводится цена за сканирование, так как стоимость зависит от размера репозитория, созданного вами рабочего процесса и используемой модели. Запустите одно сканирование для небольшого репозитория, а затем изучите страницу использования у вашего провайдера, прежде чем направлять инструмент на что-то крупное.

Запуск стека и проверка его работоспособности

./kritt start

Эта команда проверяет .env и наличие хотя бы одного набора учетных данных, после чего выполняет docker compose up --build. Первая сборка занимает много времени, так как она включает создание образов для frontend, backend, engine, executor view и базы данных. Процесс выполняется в интерактивном режиме, поэтому закрытие SSH-сессии приведет к остановке стека. Запускайте его внутри tmux или используйте фоновый режим после успешного завершения первой сборки. Ни один из этих способов не обеспечивает автоматический запуск после перезагрузки сервера. Если вы хотите, чтобы стек запускался автоматически, используйте шаблон systemd-юнита, описанный в поддержании работы self-hosted агента после перезагрузки.

docker compose up -d --build
docker compose ps

docker compose ps должен вывести список контейнеров: open-kritt-frontend, open-kritt-backend, open-kritt-engine, open-kritt-executor-view и open-kritt-db. Затем убедитесь, что backend отвечает на запросы внутри самого сервера.

curl -s http://127.0.0.1:3002/api/health

JSON-ответ означает, что backend запущен. Failed to connect to 127.0.0.1 port 3002: Connection refused указывает на то, что сервис недоступен, а docker compose logs backend поможет выяснить причину. Остановите все компоненты командой docker compose down, находясь в директории репозитория.

Дополнительная опция: docker compose exec backend npm run seed загружает демонстрационные данные. Это простой способ ознакомиться с интерфейсом перед тем, как приступать к реальному сканированию.

Доступ к интерфейсу на порту 5173 через SSH-туннель

Все сервисы в файле compose по умолчанию привязаны к 127.0.0.1: фронтенд на 5173, бэкенд на 3002, интерфейс исполнителя на 8090 и Postgres на 5432. Не меняйте эти привязки, а перенаправьте порт через SSH со своей локальной машины.

ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip

Откройте http://localhost:5173 в локальном браузере, пока выполняется эта команда. -N означает, что соединение используется только для перенаправления портов без открытия командной оболочки. Добавьте второй флаг -L 8090:127.0.0.1:8090 к той же команде, если вам также нужен доступ к интерфейсу исполнителя.

Возникает соблазн установить FRONTEND_BIND_ADDRESS=0.0.0.0 и отказаться от туннеля. Не делайте этого. У бэкенда нет экрана входа, поэтому любой, кто откроет эту страницу, сможет запускать сканирование и расходовать ваш кредит у провайдера. В отличие от него, Vaultwarden спроектирован для работы в интернете, и его защита всё равно сводится к административному токену и файлу резервной копии, чего open-kritt не предоставляет. Существует и вторая ловушка: опубликованный порт контейнера обрабатывается до того, как вступают в силу правила по умолчанию в ufw, поэтому правило ufw deny 5173 выглядит корректным, но ничего не блокирует. В статье Docker ports that bypass ufw описана цепочка правил, которая приводит к такому поведению.

Выбор размера VPS

ENGINE_MIN_FREE_STORAGE_GB по умолчанию равен 20, и движок отказывается запускать новый контейнер сканирования для задания, если объем свободного места на диске падает ниже этого значения. Собранные образы, кэш checkout, данные Postgres и рабочие области заданий находятся на одном диске, поэтому на VPS с 20 GB сканирование не запустится вовсе. Считайте 40 GB минимальным порогом и выделяйте больше, если вы сканируете крупные репозитории. Не пытайтесь сэкономить ресурсы, размещая рядом сервисы, требовательные к хранилищу, так как измеренные минимальные требования к RAM и диску в этом сравнении PhotoPrism и Immich показывают, как быстро медиабиблиотека поглотит запас, необходимый для сканирования. То же самое касается декоративных дополнений, которые кажутся легкими на фоне сканера: браузерный интерфейс, стилизующий библиотеку Jellyfin под видеопрокат 90-х всё равно тянет за собой целый медиасервер и его транскодирование на диск, поэтому выделите для него другой хост.

Память рассчитывается простой арифметикой. ENGINE_MEMORY_RESERVE_GB=2 резервирует память для движка, базы данных, API и кратковременных накладных расходов, а каждый исполнитель сканирования (scan runner) имеет резерв и жесткий лимит ENGINE_SCAN_RUNNER_MEMORY_MB=1536. Таким образом, двум воркерам требуется около 5 GB еще до запуска чего-либо другого. Движок допускает к работе только тех исполнителей, которые вписываются в оставшийся бюджет, поэтому на маломощном сервере сканирования встают в очередь, а не завершаются с ошибкой, что гораздо лучше, чем принудительное завершение процесса по нехватке памяти (OOM killer). Эта же арифметика определяет нижний порог для любого инструмента, который выделяет под каждую единицу работы отдельный контейнер; именно поэтому один контейнер и браузер OpenBot на каждого ИИ-коллегу упираются в потолок RAM гораздо раньше, чем в лимит CPU.

Две настройки очистки по умолчанию включены: ENGINE_AUTO_PRUNE_DOCKER_BUILD_CACHE и ENGINE_AUTO_PRUNE_UNUSED_DOCKER_IMAGES. После завершения задачи движок удаляет неиспользуемый кэш сборки, неиспользуемые образы и остановленные контейнеры сканирования. Образы, на которые ссылается запущенный контейнер, bind mounts, данные базы данных, учетные данные и тома сохраняются. Это еще одна причина не использовать хост совместно с другими задачами: очиститель, который вы не настраивали, работает с этим Docker daemon.

Настройки движка, которые чаще всего меняют пользователи
  • ENGINE_WORKER_COUNT: общее количество слотов для воркеров, разделяемых между этапами сканирования и постобработкой. Установите 0, чтобы приостановить прием новых заданий.
  • ENGINE_MAX_CONCURRENT_SCANS: сколько сканирований допускается одновременно. Очередь сканирований ожидает освобождения пула активных задач.
  • ENGINE_MAX_WORKERS_PER_SCAN: 0 распределяет общие слоты поровну между сканированиями.
  • ENGINE_HARNESS_TIMEOUT_SECONDS: по умолчанию 7200. Это максимальное время работы одного зависшего задания.
  • ENGINE_MIN_FREE_STORAGE_GB: минимальный порог дискового пространства. ENGINE_IGNORE_LOW_STORAGE=true отключает эту защиту, и файл предупреждает, что это может привести к заполнению диска хоста.
  • ENGINE_SCAN_RUNNER_MEMORY_MB: жесткий лимит памяти на одного исполнителя. 0 снимает ограничение.

Сканирование локального репозитория без утечки данных

LOCAL_REPOS_PATH по умолчанию использует ./local_repos и монтируется в контейнеры backend и engine по пути /local_repos, поэтому репозиторий, помещенный в эту папку на хосте, сразу становится доступен внутри контейнеров. Используйте свежий клон, а не рабочую копию. Контейнер с заданием получает копию с правами на запись, права root внутри себя и доступ в Интернет, что означает, что любые данные в этой копии могут быть изменены или отправлены за пределы сервера. Удалите файлы .env и закрытые ключи перед копированием проекта.

Что вы получаете на выходе, а что — нет

Вы получаете список потенциальных находок, отранжированных по приоритету. Вы не получаете верифицированные уязвимости. Ранжирование и дедупликация определяют порядок вашей очереди на разбор. Они не доказывают, что запись является реальной угрозой. Пост-скрипты могут попытаться выполнить валидацию и создать proof of concept, и это самый сильный сигнал, который предоставляет инструмент, но если пост-скрипт завершился неудачей, это не является доказательством ложности находки. Каждую находку всё равно изучает человек. Этот разрыв между потенциальной находкой и доказательством — причина, по которой стоит перенять подход запроса у агента доказательств, которые можно воспроизвести самостоятельно: находка, которую вы можете воспроизвести по требованию, ценнее отранжированной, которую приходится принимать на веру.

Данное руководство не делает заявлений о том, сколько реальных ошибок находит open-kritt, поскольку мы не проводили таких измерений. Любой, кто называет вам процент обнаружения для вашей кодовой базы, не запускал этот инструмент на вашем коде. Сначала просканируйте репозиторий, который вы уже хорошо знаете: находки, которые вы можете оценить самостоятельно, — это самый доступный способ калибровки.

Авторизация здесь важнее, чем в большинстве self-hosted инструментов. Агенты компилируют и исполняют код, а также обращаются к сети, поэтому этап создания proof-of-concept может затронуть работающие системы. Направляйте инструмент только на код, которым вы владеете или который уполномочены тестировать, и фиксируйте область сканирования перед запуском чего-либо. Если вы настраиваете ANTHROPIC_API_KEY и используете движок Claude Code, правила изоляции из руководства безопасный запуск Claude Code на VPS применимы и к этим агентам.

FAQ

Почему для open-kritt нужен отдельный VPS?

Потому что агенты анализа работают от имени root внутри временных контейнеров с доступом к записи в копии вашего кода и прямым выходом в интернет, а сервис движка монтирует Docker socket хоста для запуска по одному контейнеру на задачу. Любой процесс, получивший доступ к этому сокету, может запустить контейнер с доступом к файловой системе хоста, поэтому весь стек следует рассматривать как root на хосте. На выделенном VPS это приемлемый компромисс, а переустановка системы ничего не стоит. На рабочей станции это помещает ваши SSH-ключи и профили браузера в ту же зону доверия, что и сканируемый код.

Можно ли открыть порт 5173 вместо использования SSH-туннеля?

Не следует этого делать. Бэкенд поставляется без встроенной аутентификации приложения, поэтому порт — это единственная преграда между интернетом и вашими результатами сканирования и кредитами провайдера. По этой причине файл compose привязывает все сервисы к 127.0.0.1. Выполните ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip и перейдите по адресу http://localhost:5173 локально. Правило ufw не является заменой, так как опубликованный порт Docker обрабатывается до применения политики по умолчанию в ufw.

Как ограничить расходы open-kritt?

Установите жесткий лимит в консоли провайдера моделей до начала первого сканирования, так как в open-kritt нет собственных настроек бюджета. Для первых запусков сохраняйте стандартные значения параллелизма, ENGINE_WORKER_COUNT=2 и ENGINE_MAX_CONCURRENT_SCANS=1, и помните, что одна учетная запись провайдера по умолчанию позволяет выполнять до 15 параллельных вызовов корневых моделей, а сессия Codex может запускать до пяти дочерних агентов. ENGINE_WORKER_COUNT=0 приостанавливает получение новых задач и является самым быстрым способом локальной остановки.

Какую версию следует использовать?

Используйте тег, а не main. git fetch --tags с последующим git tag --list покажет доступные варианты, а v1.3.0, выпущенная 4 августа 2026 года, является самой новой на момент написания. Фиксация версии гарантирует, что пересборка через несколько месяцев создаст тот же стек, а обновление станет осознанным решением после прочтения примечаний к релизу, а не побочным эффектом клонирования в другой день.

Сканирование не запускается. Что проверить?

Сначала проверьте свободное место на диске, так как движок не запустит контейнер сканирования, если свободного места меньше ENGINE_MIN_FREE_STORAGE_GB (по умолчанию 20 GB). Затем убедитесь, что значение ENGINE_WORKER_COUNT не равно 0, так как это значение приостанавливает получение новых задач. После этого подтвердите, что учетные данные модели действительно настроены, выполнив ./kritt setup, так как GITHUB_TOKEN сам по себе не может выполнять сканирование. docker compose logs engine указывает причину, по которой задача была пропущена.