Cómo ejecutar open-kritt en un VPS con Docker
Configura open-kritt en un VPS con Docker Compose, fija una versión, accede a la UI por túnel SSH en el puerto 5173 y define el presupuesto del proveedor.
Por qué ejecutar open-kritt en un VPS y no en tu portátil
Ejecuta open-kritt en un servidor que puedas destruir y reconstruir. La herramienta ejecuta sus agentes de análisis como root dentro de contenedores de trabajos desechables, proporciona a cada uno una copia modificable de tu código y acceso directo a Internet, y monta el socket de Docker del host en su servicio de motor. Es una combinación razonable en un equipo dedicado a este trabajo. Es una mala opción en la máquina que contiene tus claves SSH.
Cuatro propiedades de la configuración predeterminada justifican esta recomendación. Las cuatro proceden del README y del archivo compose del proyecto.
Los agentes están diseñados para tener amplios privilegios. El README indica que los agentes con herramientas se ejecutan como root dentro de contenedores de trabajos desechables, con copias modificables de los repositorios y acceso directo a Internet. Así pueden instalar herramientas, compilar objetivos, ejecutar pruebas y crear pruebas de concepto. Un análisis no consiste en que un linter lea archivos. Es ejecución arbitraria de código que tú has solicitado. Ese acceso a Internet tiene riesgos en ambos sentidos: todo lo que un agente obtiene mientras investiga un objetivo es texto no confiable que llega a su prompt, igual que ocurre cuando das a un agente su propia búsqueda web.
El motor tiene el socket de Docker. docker-compose.yml monta el socket de Docker del host en el servicio de motor, porque el motor crea e inicia un contenedor de análisis por cada trabajo. Cualquier proceso que pueda acceder a ese socket puede iniciar un contenedor que monte el sistema de archivos del host. Por tanto, el motor tiene efectivamente privilegios de root sobre el host donde se ejecuta.
No hay pantalla de inicio de sesión. El backend se distribuye sin autenticación de aplicación. El acceso al puerto permite acceder a los resultados de tus análisis y al crédito de tu proveedor.
El código que analizas a menudo no es tuyo. Indicar a los agentes un repositorio de terceros significa ejecutar la compilación de ese repositorio en tu máquina, como root y con acceso a la red.
Si has leído por qué los agentes de programación deben ejecutarse en una VM desechable, este es el mismo modelo de amenazas, pero más fuerte. Asigna a open-kritt un VPS que no tenga ningún otro servicio y administra ese VPS desde una cuenta de usuario independiente con privilegios mínimos en lugar de root.
Qué hace realmente open-kritt
open-kritt (el repositorio es Kritt-ai/open-kritt y está sujeto a la licencia AGPL-3.0) divide la investigación de vulnerabilidades en tareas pequeñas, ejecuta esas tareas en paralelo mediante agentes de IA y después elimina duplicados y clasifica los resultados. Defina un flujo de trabajo como una cadena de prompts especializados. Cada paso recibe contexto estructurado de los pasos anteriores. El objetivo del análisis es un repositorio git remoto o local. El motor de análisis es Codex o Claude Code. Cuando aparece un candidato, los post-scripts opcionales pueden intentar validarlo o crear una prueba de concepto. Diseñar esa cadena es trabajo habitual con agentes, no trabajo de seguridad. Si todavía no conoce bien los prompts, las herramientas y la transferencia de contexto, aprender cómo se construyen los agentes le ayudará más a mejorar los resultados que cualquier ajuste de esta guía.
Al final se obtiene una lista clasificada de candidatos. Trátela como una cola de triaje, no como un informe.
Lo que necesita antes de empezar
- Un VPS con Ubuntu 24.04, Debian 12 o Rocky Linux 9. La documentación de instalación indica que esas son las distribuciones probadas, en x86_64 y ARM64.
- Docker Engine con el complemento Compose.
- Node.js 20 o posterior en el host, porque la CLI
./krittse ejecuta en el host y no dentro de un contenedor. - Un proveedor de modelos: un inicio de sesión de Codex, o
OPENAI_API_KEY,CODEX_API_KEY,ANTHROPIC_API_KEYoOPENROUTER_API_KEY. GITHUB_TOKENsólo si piensa analizar repositorios privados. El.env.exampleincluido lo indica claramente: un token de GitHub por sí solo no permite ejecutar análisis.
Instale primero Docker y Node 20
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USERCierre la sesión y vuelva a iniciarla para aplicar la nueva pertenencia al grupo. Después, confirme que el complemento de Compose está disponible.
docker compose versionUna cadena de versión indica que Compose está instalado como complemento. docker: 'compose' is not a docker command significa que, en su lugar, tiene el binario independiente antiguo docker-compose, y open-kritt llama a docker compose. Pertenecer al grupo docker equivale a tener acceso root en el host. Por eso, añada únicamente a ese grupo la cuenta que ejecuta open-kritt. Para consultar la configuración completa, vea ejecutar Docker en un VPS.
Ubuntu 24.04 incluye Node 18 en su propio repositorio, pero la CLI termina con un error si la versión es inferior a 20. Use NodeSource.
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -vnode -v debe mostrar v20. o una versión posterior. En Rocky Linux 9, el equivalente es sudo dnf module enable nodejs:20 -y seguido de sudo dnf install -y nodejs.
Clonar open-kritt y fijar una versión etiquetada
git clone https://github.com/Kritt-ai/open-kritt
cd open-kritt
git fetch --tags
git tag --list
git checkout v1.3.0main cambia con el tiempo. Una etiqueta no cambia. En agosto de 2026, la etiqueta más reciente es v1.3.0, publicada el 4 de agosto de 2026, y git tag --list muestra lo que existe el día en que se clona el repositorio. Al cambiar a una etiqueta, el repositorio queda en estado HEAD separado. Esto es correcto en este caso: se trata este clon como un despliegue fijado, no como una rama en la que se harán commits. Para actualizarlo más adelante, lea las notas de la versión, ejecute git fetch --tags, cambie a la nueva etiqueta y vuelva a ejecutar ./kritt start, porque start vuelve a crear las imágenes.
No ejecute ./kritt con sudo. La documentación lo indica explícitamente. La CLI administra directorios de credenciales locales del proyecto en .data/. Por tanto, si se ejecuta como root, esos directorios quedan propiedad de root y la siguiente ejecución normal no puede escribir en ellos.
Configurar el acceso a los modelos con ./kritt setup
./kritt setupEl comando crea .env a partir de .env.example si no existe, muestra el estado de cada credencial y permite configurarlas o eliminarlas. Nunca muestra los valores en el terminal. Tanto .env como el archivo de credenciales del motor se escriben con permisos 0600.
Si prefiere hacerlo manualmente:
cp .env.example .env
chmod 600 .env
mkdir -p .data/codex
chmod 700 .data/codexDespués, edite la clave del proveedor en .env y mantenga el archivo con permisos 0600. En ambos casos, el servidor tendrá una credencial válida del proveedor. Esta es otra razón para que no aloje nada más. Cree una clave exclusiva para este proyecto, de modo que revocarla más adelante no afecte a nada importante. Mantener los secretos fuera del alcance de los agentes de IA explica esta práctica con más detalle.
Establezca un límite de gasto del proveedor antes del primer análisis
open-kritt está diseñado para distribuir la carga, y esa distribución es lo que genera costes. Los valores predeterminados de .env.example en v1.3.0 son conservadores: ENGINE_WORKER_COUNT=2, descrito en el archivo como un valor predeterminado conservador para una máquina pequeña con 2 vCPU, y ENGINE_MAX_CONCURRENT_SCANS=1. Por encima de ellos están ENGINE_WORKERS_PER_ACCOUNT=15, el número máximo de llamadas simultáneas al modelo raíz permitidas en una cuenta de proveedor, y ENGINE_CODEX_MAX_SUBAGENTS_PER_SESSION=5, porque una sesión de Codex puede ejecutar hasta cinco agentes secundarios. Si aumenta el número de workers en un VPS más grande, también aumenta el número de llamadas al modelo en curso.
Nada en el repositorio limita lo que se gasta. No hay ninguna configuración de presupuesto en .env.example. Las condiciones de parada propias del motor son esos límites de los workers y ENGINE_HARNESS_TIMEOUT_SECONDS, que de forma predeterminada permite 7200 segundos por ejecución del harness. En este contexto, un harness es el bucle que sigue llamando al modelo con herramientas y contexto hasta que algo finaliza la ejecución. Por tanto, ese tiempo de espera es un límite de reloj de pared para el programa que envuelve al modelo, no un límite para lo que el modelo gasta dentro de él. Por eso, el límite máximo debe configurarse en el proveedor. Abra la consola del proveedor y establezca un límite mensual estricto antes del primer escaneo, no después. Cómo controlar el coste de un agente de IA en un VPS explica la configuración de cada proveedor.
También existe un freno local. Establecer ENGINE_WORKER_COUNT=0 pausa la recogida de trabajos nuevos, y puede cambiar los mismos valores de workers en la pantalla Settings cuando la pila esté en ejecución.
Esta guía no indica un precio por análisis, porque el coste depende del tamaño del repositorio, del flujo de trabajo que cree y del modelo que utilice. Ejecute un análisis contra un repositorio pequeño y, después, consulte la página de uso del proveedor antes de analizar algo grande.
Inicie el stack y compruebe que esté operativo
./kritt startEsto comprueba .env y al menos una credencial, y después ejecuta docker compose up --build. La primera compilación tarda porque compila las imágenes del frontend, el backend, el motor, la vista del executor y la base de datos. También se ejecuta en primer plano, por lo que cerrar la sesión SSH detiene el stack. Inícielo dentro de tmux o ejecútelo en segundo plano una vez que la primera compilación haya terminado correctamente. Ninguna de estas opciones sobrevive por sí sola a un reinicio. Si quiere que el stack vuelva a iniciarse después de reiniciar el servidor, el patrón de unidad de systemd descrito en mantener un agente autohospedado en ejecución tras los reinicios se aplica directamente.
docker compose up -d --build
docker compose psdocker compose ps debería mostrar open-kritt-frontend, open-kritt-backend, open-kritt-engine, open-kritt-executor-view y open-kritt-db. Después, compruebe que el backend responda en el propio servidor.
curl -s http://127.0.0.1:3002/api/healthUna respuesta JSON indica que el backend está activo. Failed to connect to 127.0.0.1 port 3002: Connection refused indica que no lo está, y docker compose logs backend mostrará el motivo. Detenga todo con docker compose down desde el directorio del repositorio.
Una opción adicional: docker compose exec backend npm run seed carga datos de demostración. Es una forma sencilla de revisar la interfaz antes de gastar dinero en un análisis real.
Acceder a la interfaz en el puerto 5173 mediante un túnel SSH
Todos los servicios del archivo compose se enlazan a 127.0.0.1 de forma predeterminada: el frontend en 5173, el backend en 3002, la vista del executor en 8090 y Postgres en 5432. Mantenga esos enlaces y reenvíe el puerto mediante SSH desde su propio equipo.
ssh -N -L 5173:127.0.0.1:5173 you@your-server-ipAbra http://localhost:5173 en el navegador local mientras se ejecuta ese comando. -N indica que la conexión transporta el reenvío y no abre un shell. Añada un segundo -L 8090:127.0.0.1:8090 al mismo comando cuando también necesite la vista del executor.
La opción más tentadora es establecer FRONTEND_BIND_ADDRESS=0.0.0.0 y omitir el túnel. No lo haga. El backend no tiene pantalla de inicio de sesión, por lo que cualquiera que acceda a esa página puede iniciar análisis y consumir el crédito de su proveedor. En cambio, Vaultwarden está diseñado para exponerse a Internet, y su endurecimiento sigue dependiendo del token de administrador y del archivo de copia de seguridad, controles que open-kritt no ofrece. Hay otro problema relacionado: un puerto publicado del contenedor se procesa antes de que se aplique la política predeterminada de ufw, por lo que una regla ufw deny 5173 parece correcta, pero no bloquea nada. Puertos de Docker que omiten ufw muestra la cadena de reglas que lo provoca.
Dimensionamiento del VPS
ENGINE_MIN_FREE_STORAGE_GB tiene el valor predeterminado 20, y el motor no inicia un contenedor de análisis independiente por trabajo cuando el almacenamiento libre es inferior a ese valor. Las imágenes creadas, la caché del checkout, los datos de Postgres y los espacios de trabajo de los trabajos usan el mismo disco, por lo que un VPS de 20 GB nunca inicia un análisis. Considere 40 GB como el mínimo y asígnele más espacio si analiza repositorios grandes. No intente recuperar espacio en el servidor alojando junto a él un servicio con un consumo elevado de almacenamiento, porque los mínimos medidos de RAM y disco de esta comparación entre PhotoPrism e Immich muestran lo rápido que una biblioteca multimedia consumiría el margen que necesita un análisis. Lo mismo ocurre con los complementos ornamentales que parecen no consumir recursos junto a un escáner: una interfaz web que cambia el estilo de una biblioteca de Jellyfin para convertirla en un videoclub de los años 90 sigue necesitando un servidor multimedia completo y sus transcodificaciones en el disco, así que asígnele otro host.
La memoria se calcula con una aritmética sencilla. ENGINE_MEMORY_RESERVE_GB=2 reserva memoria para el motor, la base de datos, la API y la sobrecarga temporal, y cada ejecutor de escaneo tiene una reserva y un límite estricto de ENGINE_SCAN_RUNNER_MEMORY_MB=1536. Por tanto, dos workers necesitan unos 5 GB antes de ejecutar cualquier otra cosa. El motor sólo admite los ejecutores que caben en el presupuesto restante, de modo que en un equipo pequeño los escaneos quedan en cola en lugar de fallar. Este comportamiento es mucho mejor que activar el OOM killer. La misma operación establece el mínimo para cualquier herramienta que asigne su propio contenedor a cada unidad de trabajo. Por eso el contenedor y el navegador de OpenBot para cada compañero de IA alcanza un límite de RAM mucho antes que un límite de CPU.
Dos opciones de limpieza tienen el valor predeterminado true: ENGINE_AUTO_PRUNE_DOCKER_BUILD_CACHE y ENGINE_AUTO_PRUNE_UNUSED_DOCKER_IMAGES. Cuando termina una tarea, el motor elimina la caché de compilación que no se usa, las imágenes no utilizadas y los contenedores de escaneo detenidos. Se conservan las imágenes referenciadas por un contenedor en ejecución, los bind mounts, los datos de la base de datos, las credenciales y los volúmenes. Es otra razón para no compartir el host: un proceso de limpieza que usted no configuró se ejecuta contra ese daemon de Docker.
Configuración del motor que la mayoría termina cambiando
ENGINE_WORKER_COUNT: número total de slots de workers compartidos por los pasos de escaneo y el posprocesamiento. Establézcalo en 0 para pausar la recogida de trabajos nuevos.ENGINE_MAX_CONCURRENT_SCANS: número de escaneos que se admiten simultáneamente. Los escaneos en cola esperan hasta que el grupo activo queda vacío.ENGINE_MAX_WORKERS_PER_SCAN: con el valor 0, los slots agregados se reparten por igual entre los escaneos.ENGINE_HARNESS_TIMEOUT_SECONDS: 7200 de forma predeterminada. Es el tiempo máximo que puede durar un único trabajo descontrolado.ENGINE_MIN_FREE_STORAGE_GB: mínimo de almacenamiento.ENGINE_IGNORE_LOW_STORAGE=truedesactiva la protección, y el archivo advierte de que esto puede llenar el disco del host.ENGINE_SCAN_RUNNER_MEMORY_MB: límite estricto de memoria por ejecutor. El valor 0 elimina el límite.
Analizar un repositorio local sin exponerlo
LOCAL_REPOS_PATH usa ./local_repos de forma predeterminada y se monta mediante bind en los contenedores de backend y engine en /local_repos, por lo que un repositorio que coloque en esa carpeta del host aparece inmediatamente dentro de los contenedores. Use un clon nuevo, no su árbol de trabajo. El contenedor del trabajo obtiene una copia con permisos de escritura, acceso como root dentro del propio contenedor y acceso saliente a Internet. Esto significa que cualquier elemento de esa copia puede modificarse o enviarse fuera del equipo. Elimine los archivos .env y las claves privadas antes de copiar un proyecto.
Lo que recibe y lo que no
Recibe hallazgos candidatos ordenados por prioridad. No recibe vulnerabilidades verificadas. La clasificación y la eliminación de duplicados determinan el orden de la cola de triaje. No demuestran que una entrada sea real. Los scripts posteriores pueden intentar validar el hallazgo y crear una prueba de concepto. Esa es la señal más sólida que ofrece la herramienta. Sin embargo, que un script posterior falle no demuestra que el hallazgo sea falso. Una persona debe revisar todos los candidatos. Esa diferencia entre un candidato y una prueba explica por qué conviene pedir a un agente pruebas que pueda volver a ejecutar usted mismo: un hallazgo que puede reproducir bajo demanda vale más que uno clasificado que debe aceptar sin verificar.
Esta guía no afirma cuántos errores reales detecta open-kritt, porque no lo hemos medido. Quien cite una tasa de detección para su base de código no la ha ejecutado contra su base de código. Primero analice un repositorio que ya conozca bien: los hallazgos que puede evaluar usted mismo son la calibración más barata disponible.
La autorización es más importante aquí que con la mayoría de las herramientas autoalojadas. Los agentes compilan y ejecutan código, y acceden a la red, por lo que un paso de prueba de concepto puede interactuar con sistemas activos. Dirija la herramienta a código que sea de su propiedad o que tenga autorización contractual para probar, y documente el alcance objetivo antes de ejecutar cualquier cosa. Si configura ANTHROPIC_API_KEY y usa el motor Claude Code, las prácticas de sandboxing descritas en ejecutar Claude Code de forma segura en un VPS también se aplican a estos agentes.
FAQ
¿Por qué open-kritt necesita su propio VPS?
Porque sus agentes de análisis se ejecutan como root dentro de contenedores de trabajo desechables con copias modificables de su código y acceso directo a Internet. Además, el servicio del motor monta el socket de Docker del host para poder iniciar un contenedor por trabajo. Cualquier proceso que acceda a ese socket puede iniciar un contenedor que monte el sistema de archivos del host. Por tanto, toda la pila debe considerarse equivalente a root en ese host. En un VPS dedicado, este riesgo es aceptable y reconstruir el sistema no le cuesta nada. En su estación de trabajo habitual, las claves SSH y los perfiles del navegador quedan dentro del mismo límite de confianza que el código que está analizando.
¿Puedo exponer el puerto 5173 en lugar de usar un túnel SSH?
No debería hacerlo. El backend se distribuye sin autenticación de aplicación. Por tanto, el puerto es la única barrera entre Internet y los resultados de sus análisis y el crédito de su proveedor. El archivo compose enlaza todos los servicios con 127.0.0.1 por ese motivo. Ejecute ssh -N -L 5173:127.0.0.1:5173 you@your-server-ip y acceda localmente a http://localhost:5173. Una regla de ufw no sustituye esta medida, porque un puerto publicado por Docker se procesa antes de que se aplique la política predeterminada de ufw.
¿Cómo evito que open-kritt gaste más de lo previsto?
Establezca un límite estricto en la consola de su proveedor de modelos antes del primer análisis, porque open-kritt no tiene su propia configuración de presupuesto. Mantenga los valores de concurrencia incluidos de forma predeterminada durante las primeras ejecuciones, ENGINE_WORKER_COUNT=2 y ENGINE_MAX_CONCURRENT_SCANS=1, y recuerde que una cuenta de proveedor permite de forma predeterminada hasta 15 llamadas simultáneas al modelo root, mientras que una sesión de Codex puede ejecutar hasta cinco agentes secundarios. ENGINE_WORKER_COUNT=0 detiene la recogida de trabajos nuevos y es la forma local más rápida de detener el sistema.
¿Qué versión debería descargar?
Una etiqueta, nunca main. git fetch --tags seguido de git tag --list muestra lo que está disponible, y v1.3.0, publicada el 4 de agosto de 2026, es la versión más reciente en el momento de redactar este texto. Fijar una versión garantiza que una reconstrucción realizada meses después produzca la misma pila. También convierte la actualización en una decisión que se toma después de leer las notas de la versión, en lugar de un efecto secundario de clonar en otro día.
Un análisis nunca comienza. ¿Qué debo comprobar?
Compruebe primero el espacio libre en disco, porque el motor no iniciará un contenedor de análisis por trabajo cuando el almacenamiento libre sea inferior a ENGINE_MIN_FREE_STORAGE_GB, cuyo valor predeterminado es 20 GB. Después, compruebe que ENGINE_WORKER_COUNT no sea 0, porque ese valor detiene la recogida de trabajos nuevos. A continuación, confirme que las credenciales de un modelo estén configuradas realmente mediante ./kritt setup, porque un GITHUB_TOKEN por sí solo no puede ejecutar análisis. docker compose logs engine indica el motivo por el que se omitió el trabajo.