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

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

Узнайте, как безопасно запустить open-kritt на сервере. Инструкция по настройке Docker Compose, фиксации версий, пробросу SSH-туннеля к порту 5173 и лимитам бюджета 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) разбивает исследование уязвимостей на небольшие задачи, выполняет их параллельно с помощью ИИ-агентов, а затем удаляет дубликаты и ранжирует полученные результаты. Вы определяете рабочий процесс как цепочку целенаправленных промптов, и каждый шаг получает структурированный контекст от предыдущих этапов. Целью сканирования является удаленный или локальный git-репозиторий. Механизмом анализа выступает Codex или Claude Code. После обнаружения кандидата на уязвимость можно запустить дополнительные скрипты для проверки или создания proof of concept.

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

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

  • 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. Поэтому верхний предел должен быть установлен на стороне провайдера. Откройте консоль управления провайдером и установите жесткий ежемесячный лимит до начала первого сканирования, а не после него. В Контроль расходов на 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 и обойтись без туннеля. Не делайте этого. У бэкенда нет экрана входа, поэтому любой, кто получит доступ к этой странице, сможет запускать сканирование и расходовать ваш кредит у провайдера. Существует и вторая скрытая опасность: опубликованный порт контейнера обрабатывается до применения политики по умолчанию в ufw, поэтому правило ufw deny 5173 выглядит корректным, но ничего не блокирует. В Docker ports that bypass ufw описана цепочка правил, которая приводит к этому поведению.

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

ENGINE_MIN_FREE_STORAGE_GB по умолчанию имеет значение 20, и движок отказывается запускать новый контейнер сканирования для задания, если объем свободного места на диске падает ниже этого значения. Собранные образы, кэш checkout, данные Postgres и рабочие области заданий находятся на одном диске, поэтому на VPS с 20 ГБ сканирование не запустится вовсе. Считайте 40 ГБ минимальным порогом и выделяйте больше места, если вы сканируете крупные репозитории.

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

Две настройки очистки по умолчанию включены: ENGINE_AUTO_PRUNE_DOCKER_BUILD_CACHE и ENGINE_AUTO_PRUNE_UNUSED_DOCKER_IMAGES. После завершения задачи движок удаляет неиспользуемый кэш сборки, неиспользуемые образы и остановленные контейнеры сканирования. Образы, на которые ссылается запущенный контейнер, bind-монтирования, данные базы данных, учетные данные и тома сохраняются. Это еще одна причина не использовать хост совместно с другими задачами: процесс очистки, который вы не настраивали, работает с этим 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 инструментов. Агенты компилируют и исполняют код, а также обращаются к сети, поэтому этап создания доказательства концепции может затронуть работающие системы. Направляйте инструмент только на тот код, которым вы владеете или который уполномочены тестировать, и фиксируйте целевую область (scope) перед запуском чего-либо. Если вы настраиваете 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 указывает причину, по которой задача была пропущена.