Operación self-hosted
En una instalación propia, la persona que opera Thulu actualiza la versión, decide cuándo volver atrás, saca backups y limpia lo que queda en el host. Thulu nunca cambia su propia versión: la pantalla “Actualizaciones” informa qué hay y da el comando, y el cambio se corre a mano con la CLI thulu en la máquina que administra la instalación.
Todo lo de esta página aplica sólo a instalaciones self-hosted. En la SaaS lo hace el equipo de Thulu.
Actualizar una instalación Docker
Sección titulada «Actualizar una instalación Docker»-
Fijate si hay una versión nueva. Cuando hay una, el pie de la barra lateral muestra un punto azul al lado de la versión. Hacé clic ahí, o andá a “Configuración” → “Actualizaciones”.

El punto azul sólo lo ve el operador: indica que hay una versión más nueva en los canales permitidos. -
Leé el panel “Versión” y la lista de “Versiones disponibles”. Cada versión dice cuántas migraciones trae, desde qué versiones se puede saltar, si volver atrás necesita restaurar la base y qué variables nuevas exige. “Buscar ahora” fuerza una búsqueda; si no, Thulu busca cada 12 horas.

0.3.2 no trae migraciones y volver a 0.3.1 no requiere restaurar la base. El comando está listo para copiar. -
Descargá el paquete de cambios con “Descargar paquete de cambios” (Markdown) o “JSON”. Es el documento para revisar o adjuntar al ticket de cambio: versiones, cada imagen por digest, migraciones, variables obligatorias, pasos manuales, el plan de ejecución y cómo volver. La descarga queda en el registro de auditoría.
-
Copiá el comando con “Copiar” y abrí una terminal en el host de la instalación, en el directorio donde está
deploy/. -
Si querés, generá el paquete desde la terminal para ver además qué archivos de
deploy/cambian (la UI no tiene acceso al disco para comparar eso):Ventana de terminal thulu update -check -version 0.3.2 -o change-0.3.2.md -
Corré la actualización y confirmá cuando pregunte “¿Actualizar ahora?”:
Ventana de terminal thulu update -version 0.3.2 -api-key-file ~/.thulu-operator-keyCon
-api-key-file(oOCTOPUS_API_KEYdefinida) el resultado llega al historial.-operatorcambia el nombre que aparece en la columna “Por”. Si la versión trae pasos manuales, la CLI pide que los confirmes con-ack-manual-steps. Con una base de datos externa, a la que la CLI no llega, pide-backup-confirmedpara dejar constancia de que sacaste tu propio backup. -
Volvé a “Actualizaciones” y mirá el “Historial”. Cada corrida aparece con su resultado y quién la corrió; el arranque del daemon en la versión nueva aparece aparte.

La primera corrida del 29 de octubre falló porque alguien había editado deploy/docker-compose.yml a mano. La siguiente, nueve minutos después, salió bien.
Qué hace thulu update -version X
Sección titulada «Qué hace thulu update -version X»El comando escribe la versión destino y corre thulu apply, que sigue este orden. Si algo falla antes del paso 5, no cambió nada; si falla después, vuelve solo a la versión anterior.
| Paso | Qué hace |
|---|---|
| 1. Verifica | Baja el manifiesto de la release y verifica su firma con la clave embebida en el binario. Cada imagen y el chart están nombrados por digest, y se verifica la firma de cada uno antes de bajarlo. |
| 2. Usa la CLI de la versión destino | La CLI de la versión X aplica la versión X: la baja, compara su sha256 con el manifiesto y le pasa el control. |
| 3. Preflight | El salto está permitido, están todas las variables obligatorias, los pasos manuales están confirmados, nadie editó a mano un archivo de deploy/, hay espacio en disco y no hay otro update corriendo. |
| 4. Backup | Con el Postgres incluido, un snapshot (pg_dump más /data) en backups/, asociado a la versión que dejás. |
| 5. Cambia | Baja las imágenes por digest, reescribe los archivos de deploy/, escribe el bloque administrado de deploy/.env y recrea el stack. Tu docker-compose.override.yml se aplica siempre encima. |
| 6. Confirma | Espera /health/ready y comprueba que /info informe la versión nueva. Arrancar con la imagen vieja cuenta como falla. |
| 7. Informa | Escribe deploy/.octopus-update.json y manda el resultado al registro de auditoría. Si el envío falla es una advertencia, no un update fallido. |
Se puede saltar desde las dos últimas versiones menores. Una instalación más vieja pasa primero por la menor más vieja soportada; apply rechaza el salto si la release no lo permite. Contá con un corte de alrededor de un minuto mientras se recrea el contenedor del daemon.
Volver a una versión anterior
Sección titulada «Volver a una versión anterior»Una instalación Docker conserva las imágenes y el snapshot de las últimas 3 versiones, contando la que corre (OCTOPUS_KEEP_VERSIONS), así que volver no necesita el registry. “Volver atrás” las lista con el comando exacto de cada una.

- En “Configuración” → “Actualizaciones” → “Volver atrás”, buscá la versión y apretá “Copiar”.
- En la terminal del host, corré el comando. Hay dos casos:
thulu update -to 0.3.0: la versión es elrollback_tode la que corre. Las migraciones de la versión actual sólo agregan cosas que esa versión sabe leer, así que cambian las imágenes y la base queda como está.thulu update -to 0.2.1 -restore octopus_20261005_141610.sql: cualquier otra versión guardada. La base vuelve al snapshot tomado al dejar esa versión, y se pierde todo lo escrito desde entonces.
- Confirmá cuando pregunte “¿Volver ahora?”. La terminal muestra antes qué imágenes cambian y qué pasa con la base.
Desde la terminal, thulu update -rollback vuelve a la versión anterior, thulu update -kept lista las versiones guardadas con su comando, y thulu update -keep 0.3.0 fija una para que nunca se borre (-unkeep la libera). Con una base externa, la restaurás vos y pasás -restore external.
Actualizar en Kubernetes con Helm
Sección titulada «Actualizar en Kubernetes con Helm»En Kubernetes el proceso es el mismo comando, corrido desde una máquina con helm, acceso al cluster y el directorio de la instalación que dejó thulu init:
thulu update -check -version 0.3.2 -o change-0.3.2.mdthulu update -version 0.3.2La CLI verifica la firma del chart y de cada imagen, y corre helm upgrade --install octopus <chart> --namespace octopus --wait --atomic --timeout 10m con cada imagen fijada por digest. Los pods viejos siguen atendiendo hasta que los nuevos están listos, y si nunca llegan, Helm revierte solo. Para volver, thulu update -to <versión> usa el historial de Helm; en Kubernetes “Volver atrás” no lista versiones y la versión a la que volver se saca del “Historial”.
Instalaciones sin acceso a internet
Sección titulada «Instalaciones sin acceso a internet»En una máquina que llega a GitHub y al registry, thulu mirror 0.3.2 -to registry.empresa.com/octopus -dir /srv/thulu-releases verifica la release y copia imágenes (con sus firmas), chart, manifiesto firmado, bundle de deploy y binarios. En la instalación, OCTOPUS_UPDATE_SOURCE apunta a ese directorio (https://… o file://…) y OCTOPUS_IMAGE_REGISTRY al registry interno. Las firmas se verifican igual que con los originales. OCTOPUS_UPDATE_SOURCE=off apaga las búsquedas y la pantalla muestra “búsquedas apagadas”.
Backups
Sección titulada «Backups»thulu update saca su propio snapshot antes de cambiar nada. Para backups periódicos está deploy/backup.sh, que arma un .tar.gz con un pg_dump y el directorio de datos (worktrees, repos, adjuntos, contadores de uso), legible sólo por su dueño.
OCTOPUS_COMPOSE_FILE=deploy/docker-compose.yml ./deploy/backup.sh /var/backups/thuluProgramalo en cron, por ejemplo todos los días a las 3:
0 3 * * * cd /opt/thulu && OCTOPUS_COMPOSE_FILE=deploy/docker-compose.yml ./deploy/backup.sh /var/backups/thulu >> /var/log/thulu-backup.log 2>&1Como root en el nodo, lee el volumen local del chart y corre pg_dump adentro del pod de Postgres:
OCTOPUS_BACKUP_SOURCE=kubernetes ./deploy/backup.sh /var/backups/thulu| Variable | Para qué |
|---|---|
OCTOPUS_BACKUP_KEEP |
Cuántos snapshots se guardan en total, los del script y los del updater juntos. Default 5. El snapshot de cada versión guardada no se borra nunca. |
OCTOPUS_BACKUP_REMOTE |
usuario@host:dir: copia cada archivo por rsync sobre ssh. Un backup local no sobrevive a la pérdida del disco. |
OCTOPUS_BACKUP_REMOTE_KEEP |
Cuántas copias quedan en el destino remoto. Default 14. |
OCTOPUS_BACKUP_AGE_RECIPIENT |
Cifra la copia remota con age (la local no). |
El dump tiene las credenciales guardadas cifradas con OCTOPUS_SECRETBOX_KEY, y no la clave. Guardá la clave en otro lado: sin ella, un backup restaurado no puede leer las credenciales.
El panel “Backups” de “Actualizaciones” lee el resultado que deja cada corrida del script: el último backup con su archivo y tamaño, cuántos snapshots se guardan contra OCTOPUS_BACKUP_KEEP, si la copia fuera del host anduvo, y el comando para restaurarlo. Si nunca corrió, el panel lo dice.
Para restaurar a mano: pará el daemon (docker compose -f deploy/docker-compose.yml stop octopus), corré RESTORE=1 OCTOPUS_COMPOSE_FILE=deploy/docker-compose.yml ./deploy/backup.sh <archivo.tar.gz> (pide confirmación antes de pisar el directorio de datos), volvé a levantar el stack y verificá /health/ready. Restaurar pisa /data: se pierde lo escrito después del backup.
Limpieza y retención
Sección titulada «Limpieza y retención»Thulu borra lo que crea. Cada contenedor, pod, volumen y red que levanta lleva una etiqueta de Thulu, y la limpieza elige siempre por etiqueta, así que no toca otros proyectos del mismo host o cluster.
| Qué | Cuándo se va |
|---|---|
| Contenedor de un agente | Al terminar de procesar su corrida. Si quedó alguno, el janitor lo borra 2 h después de que salió. |
| Contenedor de chat | Tras el tiempo de inactividad, al borrar o reiniciar el chat, o 2 h después de salir. |
| Sandbox | Cuando la tarea llega a una etapa final, al borrar la tarea, o 6 h después de que la tarea quedó fallida, bloqueada o sin turnos. |
| Worktree de la tarea | En etapa final o al borrar la tarea. Una tarea trabada retention.stuck_worktree_days días se “estaciona”: los cambios pendientes se commitean en la rama de la tarea y se borra el checkout. Relanzarla retoma el trabajo. |
| Adjuntos, logs, salidas, uso y keys de una tarea | Al borrar la tarea. |
| Todo lo de un workspace | Al borrar el workspace (ver Workspaces y equipo). |
| Imágenes viejas de Thulu | En cada pasada del janitor, salvo las de las versiones guardadas. |
El janitor pasa cada hora, en Docker y en Kubernetes. Además mira el espacio libre del directorio de datos cada 5 minutos y, por debajo del umbral, limpia en el momento.
Plazos de retención
Sección titulada «Plazos de retención»El operador los cambia en “Configuración → Salud → Retención y limpieza”, con el valor en días (0 = para siempre; un campo vacío vuelve al default). El panel también muestra la última pasada del janitor y el disco libre. Por API es PUT /settings/<clave>:
curl -X PUT https://thulu.empresa.com/settings/retention.run_logs_days \ -H "Authorization: Bearer $OCTOPUS_API_KEY" -H "Content-Type: application/json" -d '60'| Clave | Default | Qué cubre |
|---|---|---|
retention.run_logs_days |
30 | Logs y salidas de corridas, transcripciones de chat |
retention.sessions_days |
90 | Filas de uso por corrida. El costo diario agregado se conserva. |
retention.webhook_deliveries_days |
30 | Log de entregas de webhooks |
retention.run_keys_days |
7 | Keys de corridas y chats vencidas o revocadas. Las de personas y operador no se borran. |
retention.sandbox_rows_days |
30 | Filas de sandboxes y chats ya desarmados |
retention.stuck_worktree_days |
14 | Cuándo se estaciona el worktree de una tarea trabada |
retention.cache_metrics_days |
90 | Historial de la caché de dependencias (ver Infraestructura) |
janitor.disk_free_min_percent |
10 | Porcentaje de disco libre que dispara una limpieza; 0 la apaga |
audit.retention_days |
sin definir | Registro de auditoría; opcional (ver Seguridad y auditoría) |
Un log se borra a los 30 días y su fila de uso a los 90, así que en una corrida vieja el link al log deja de andar antes.
thulu gc
Sección titulada «thulu gc»Lista lo que Thulu dejó en el host y nada usa: contenedores parados, imágenes viejas, caché de builds, snapshots fuera de retención. Cada lista viene agrupada en “Contenedores”, “Imágenes”, “Volúmenes” y “Redes”, con una sección “Se conservan” que dice por qué guarda cada imagen.
thulu gc # sólo muestrathulu gc -apply # borra lo listadothulu gc -unclaimed # suma imágenes de Thulu que ninguna versión reclamaMover un workspace a otra instalación
Sección titulada «Mover un workspace a otra instalación»thulu export empaqueta un workspace en un .tgz: tableros con sus etapas y tipos, proyectos con sus entornos y el script de arranque vigente, métricas y dashboards, tareas con adjuntos, comentarios, reportes, eventos y casos de prueba, el catálogo de agentes y skills, los MCP registrados y la configuración de la instalación. Los ids se conservan, así que las referencias cruzadas siguen resolviendo.
No viajan los secretos (credenciales, claves LLM, tokens de ingesta), las personas y sus permisos, las API keys, el registro de auditoría, el uso y costos, los chats ni los logs de corridas. El bundle trae un checklist de los secretos que hay que volver a cargar.
Con la CLI descargada, export e import entran solos al contenedor del daemon (docker compose exec, o kubectl exec en Kubernetes), donde están la base y los adjuntos, así que el stack tiene que estar corriendo.
-
En el host de origen, exportá.
-workspaceacepta el id o el slug, y con un solo workspace se puede omitir (thulu workspace listlos lista):Ventana de terminal thulu export -workspace nube-andina -out nube-andina.tgz -
En el host de destino, creá el workspace si todavía no existe. El import usa por defecto el workspace del bundle; si ese id no existe acá, se detiene y pide
-workspace:Ventana de terminal thulu workspace create -name "Nube Andina" -slug nube-andina -owner-email <email> -
Copiá el archivo al host de destino e importalo:
Ventana de terminal thulu import -workspace nube-andina nube-andina.tgzEl import respeta el orden de dependencias y se puede repetir: las tareas, proyectos y comentarios que ya existen quedan como están, así que un segundo intento termina un import cortado. Los tableros y los MCP que ya existen se pisan con lo del bundle. La configuración de la instalación de origen se aplica sólo con
-with-settings, porque alcanza a todos los workspaces del destino. Al final imprime un resumen con lo que escribió, las advertencias y la lista de secretos para volver a cargar;-jsonda los conteos en JSON. -
Volvé a cargar a mano cada secreto del checklist en Credenciales y motores, reemití los tokens de ingesta y configurá
ingest.public_urlcon la dirección del host nuevo (el import la saltea a propósito).
Desinstalar
Sección titulada «Desinstalar»thulu uninstall # muestra todo lo que se borraríathulu uninstall -yes # baja el stack y borra contenedores, imágenes, red y configuración de Thuluthulu uninstall -yes -purge-data # además la base, los volúmenes de datos, deploy/.env y los backupsSin -purge-data quedan los volúmenes de datos, deploy/.env (tiene la contraseña de la base y la clave que cifra las credenciales) y los backups, así que una reinstalación vuelve a abrirlos. -purge-data no tiene vuelta atrás: exportá antes lo que necesites. En una instalación con Helm imprime los comandos helm uninstall y kubectl delete namespace en vez de correrlos. El binario thulu no se borra; el comando imprime su ruta.
Problemas comunes
Sección titulada «Problemas comunes»- “No se ofrecen porque fallaron la verificación”: la firma del manifiesto de esas versiones no coincide con la clave embebida. Pasa con un mirror que alguien modificó o con builds de preview sin
cosignen elPATH. No las instales. - “Falló la última búsqueda”: el daemon no llegó a la fuente de releases. Detrás de un proxy, el daemon respeta
HTTPS_PROXY. Con un repo privado,OCTOPUS_UPDATE_GITHUB_TOKEN. - El preflight se detiene con una diferencia de archivos: alguien editó
deploy/docker-compose.yml. Pasá el cambio adocker-compose.override.ymly volvé a correr el update. - El historial no muestra la corrida que hiciste: el host no tenía
OCTOPUS_API_KEYde operador, o la key no tiene rol admin o el permisosettings. La CLI lo avisa al final como advertencia. - “Todavía no hay versiones guardadas”: la lista de versiones guardadas arranca con el primer
thulu apply. Una instalación que nunca se actualizó con la CLI no tiene a dónde volver sin un backup.