Mantenimiento rutinario
La mayoría de los incidentes de UltraTorrent son de combustión lenta: un disco que se llena, un conteo de torrents que se pasa del techo de fallos de rTorrent, un índice que nunca se reconstruyó, un backup que lleva tres meses fallando en silencio. Ninguno se anuncia. Todos se atrapan con una rutina que toma minutos.
Propósito
Atrapar los problemas mientras todavía son baratos.
Cuándo usar esto
Pon un recordatorio recurrente. El chequeo diario toma 60 segundos; el mensual, media hora.
Requisitos previos
- Acceso de shell al host.
- Un backup que funcione.
Video próximamente.
La rutina de un vistazo
Diario (60 segundos)
Un solo comando te dice casi todo lo que necesitas:
cd /path/to/ultratorrent
# 1. ¿Está todo arriba y saludable?
docker compose ps
# 2. ¿Algo gritando?
docker compose logs --since 24h backend | grep -iE "error|fatal|refused" | tail -20
# 3. ¿Está el motor en línea?
docker compose exec backend wget -qO- http://127.0.0.1:4000/api/system/live
Lo que estás buscando:
| Señal de alerta | Significado | Ve a |
|---|---|---|
Un container muestra Restarting | Está en bucle de fallos | Arranque |
Un container muestra unhealthy | El healthcheck está fallando (p. ej. el puerto SCGI de rTorrent no está escuchando) | Motores |
blocked internal address | La protección SSRF está bloqueando tu indexador | SSRF |
internal_error: priority_queue_insert | El bug de fallo de rTorrent | rTorrent |
| Descargas a 0 B/s en todo | Posiblemente torrents muertos ocupando todas las ranuras de la cola | Cola |
restart: unless-stopped significa que Docker lo sigue levantando, así que docker compose ps puede verse saludable mientras el proceso muere cada veinte minutos. La verdad está en
RestartCount — mira el chequeo semanal.
Semanal (10 minutos)
1. Espacio en disco
La causa más común de un stack que de repente deja de funcionar es un disco lleno. Postgres en particular falla de maneras confusas cuando no puede escribir.
df -h
# ¿Cuáles volúmenes de Docker se lo están comiendo?
docker system df -v | head -30
# El árbol de descargas casi siempre es el culpable
du -sh "$(docker volume inspect ultratorrent_downloads --format '{{ .Mountpoint }}')"
Si Docker mismo está inflado (imágenes viejas, caché de build muerto):
docker system prune -f # seguro: elimina containers detenidos e imágenes colgantes
docker builder prune -f # seguro: elimina el caché de build
docker system prune --volumesElimina los volúmenes sin usar — y se puede llevar tu base de datos con él. Nunca
añadas --volumes en un host que corre UltraTorrent.
2. ¿El motor está fallando calladito?
docker inspect --format '{{.Name}} restarts={{.RestartCount}}' \
$(docker compose ps -q) 2>/dev/null
Anota el número. Un RestartCount que sube semana tras semana es un bucle de
fallos, aunque el container se vea bien. Para rTorrent, eso es el
bug de fallo de 0.9.8
y te está diciendo que ya se te quedó chiquito el motor.
3. Trabajos atascados
Como los cuerpos de los trabajos corren en el mismo proceso, un reinicio los deja huérfanos. La reconciliación al arranque ahora los marca como fallidos automáticamente — pero verifica que nada esté trabado mientras corre:
docker compose exec postgres psql -U ultratorrent -d ultratorrent -c "
SELECT type, status, progress, \"createdAt\"
FROM media_processing_jobs
WHERE status IN ('queued','running')
ORDER BY \"createdAt\";"
Un trabajo que lleva horas en running al 0% está huérfano. Mira
Trabajos atascados en running.
4. Descargas fallidas
Revisa el registro de auditoría buscando download.failed. Pero conoce el falso positivo:
never registered within 6sEn builds más viejos, los magnets se marcaban como fallidos si no se registraban en ~6 segundos — mientras descargaban perfectamente. En un caso real, 256 de 257 "fallos" en realidad habían cargado, con una mediana de ~53 segundos. Si ves una avalancha de estos, lo que necesitas es la solución, no una investigación.
5. ¿El backup corrió de verdad?
ls -lh /mnt/backup/ultratorrent-*.dump | tail -5
Revisa la fecha y el tamaño. Un dump de 0 bytes es un backup fallido que salió con 0.
6. Poda los torrents muertos
Los torrents con cero seeders nunca terminan y — algo crítico — un magnet con 0 seeders sigue ocupando una ranura de descarga activa todo el tiempo que lo intenta. Si los dejas, bloquean la cabeza de tu cola entera. Elimínalos, o activa la cola de estacionamiento.
Mensual (30 minutos)
1. Actualiza
Mira Actualizar para el procedimiento completo. La versión corta:
# 1. HAZ UN BACKUP PRIMERO. Siempre.
docker compose exec -T postgres pg_dump -U ultratorrent -d ultratorrent -Fc \
> "pre-upgrade-$(date +%F).dump"
cp .env "pre-upgrade-env-$(date +%F)"
# 2. Descarga y reconstruye.
git pull
docker compose up -d --build
# 3. Observa la migración aterrizar. Aquí es donde aparece P3009 si va a aparecer.
docker compose logs -f backend
# 4. COMPRUEBA que el código nuevo está corriendo (no una imagen en caché):
docker compose exec backend wget -qO- http://127.0.0.1:4000/api/system/version
Ese último paso importa más de lo que parece. El endpoint de versión reporta el commit de git horneado en la imagen. Si el commit no cambió después de reconstruir, tu imagen no se reconstruyó y sigues corriendo el código viejo mientras crees lo contrario.
| Riesgo de la actualización | Vigila |
|---|---|
| Una migración falla a mitad de camino | P3009 → resuélvelo |
| Construcciones largas de índices | Ahora se construyen en tiempo de ejecución en segundo plano — la app se queda arriba pero lenta hasta que terminen |
| Trabajos en vuelo | Los mata el reinicio; se reconcilian (se marcan fallidos) al arranque. Vuelve a correr cualquier escaneo/importación que estuviera corriendo |
| Nueva variable de entorno requerida | El backend se niega a arrancar. Lee el log; revisa Entorno |
2. Revisa el log de auditoría
El registro de auditoría anota el actor, la acción, el objeto, el resultado, la IP y el user agent de toda acción destructiva o relevante para la seguridad — y ahora nombra el medio al que apuntó una fila en vez de mostrar un id opaco.
Busca:
- Inicios de sesión fallidos (
auth.loginconresult: failure) — se registran con el usuario intentado. Un grupo de ellos es significativo. Ojo que un reto de 2FA pendiente deliberadamente no cuenta como fallo, así que lo que ves es real. torrents.delete_data— alguien borró datos del disco.files.delete/files.cleanup— destrucción desde el gestor de archivos.- Cambios de rol — quién otorgó qué.
- Cambios de configuración — especialmente
settings.update_root_path.
Accede a esto en Auditoría en la UI (requiere audit.view), o GET /api/audit.
Mira Auditoría.
3. Mantenimiento de la base de datos
# Refresca las estadísticas del planificador — un plan viejo es un plan lento.
docker compose exec postgres psql -U ultratorrent -d ultratorrent -c "ANALYZE;"
# Revisa el bloat / las tuplas muertas
docker compose exec postgres psql -U ultratorrent -d ultratorrent -c "
SELECT relname, n_live_tup, n_dead_tup,
pg_size_pretty(pg_total_relation_size(relid)) AS size
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;"
El autovacuum normalmente se encarga del resto. Si una tabla tiene un conteo de tuplas muertas altísimo y el autovacuum claramente no está dando abasto:
docker compose exec postgres psql -U ultratorrent -d ultratorrent \
-c "VACUUM (ANALYZE, VERBOSE) media_items;"
Y verifica que tus índices de trigramas sigan válidos — una reconstrucción interrumpida deja un índice INVALID que el planificador ignora en silencio para siempre:
SELECT c.relname, i.indisvalid
FROM pg_class c JOIN pg_index i ON i.indexrelid = c.oid
WHERE c.relname LIKE '%trgm%';
Todos tienen que estar en true. Mira
Rendimiento.
4. Corre un simulacro de restauración
Este es el punto que la gente se salta, y es el que importa. Un backup que nunca has restaurado es un rumor.
Sigue el simulacro. Los dos chequeos que de verdad prueban que tu backup está sano:
- El 2FA funciona en una cuenta restaurada → tu
ENCRYPTION_KEYcoincidía con el dump. - La prueba de un indexador pasa → la clave API cifrada se descifró.
Si cualquiera de los dos falla, tu .env y tu dump no coinciden, y acabas de descubrir —
barato — que tu backup estaba incompleto.
5. Revisa la salud de los indexadores
- ¿Cada indexador tiene un
minSeedersconfigurado? Un indexador sin uno te va a entregar cadáveres de 0 seeders que tapan la cola. - ¿Hay algún indexador fallando en cada petición? Los fallos por indexador están aislados — un indexador roto no tumba la búsqueda entera, así que puede pudrirse sin que nadie lo note por meses.
- Si uno devuelve HTTP 429 en todo, lee la entrada del 429 antes de que pierdas una tarde ajustando límites de tasa.
Trimestral / anual
- Rota los secretos JWT. Barato — a todo el mundo se le cierra la sesión, y nada más pasa. Mira Rotar secretos.
- Revisa usuarios y roles. Elimina a la gente que se fue. Recuerda que
POWER_USERincluye todos losfiles.*, incluyendo delete. - Vuelve a revisar tu exposición. ¿Siguen sin publicarse los puertos del motor y de los servicios acompañantes? Corre el fragmento de auditoría de seguridad.
- Reevalúa tu motor. Si tu conteo de torrents creció a los cientos, estás en tiempo prestado con rTorrent.
ENCRYPTION_KEY como mantenimiento rutinarioEs destructivo — invalida todo secreto TOTP, toda clave API de indexador, la clave de Prowlarr y las contraseñas de los motores. Rótala solo en respuesta a una filtración, y sigue el procedimiento.
Ejemplos
Un script semanal de salud, de una sola pasada
#!/usr/bin/env bash
# weekly-check.sh — córrelo desde el directorio de compose
set -euo pipefail
cd "$(dirname "$0")"
echo "=== Containers ==="
docker compose ps
echo -e "\n=== Restart counts (a climbing number = a crash loop) ==="
docker inspect --format '{{.Name}} restarts={{.RestartCount}}' $(docker compose ps -q)
echo -e "\n=== Disk ==="
df -h / | tail -1
echo -e "\n=== Errors, last 7 days ==="
docker compose logs --since 168h backend 2>/dev/null \
| grep -icE "error|fatal" || echo 0
echo -e "\n=== Stuck jobs ==="
docker compose exec -T postgres psql -U ultratorrent -d ultratorrent -tAc \
"SELECT count(*) FROM media_processing_jobs WHERE status IN ('queued','running');"
echo -e "\n=== Trigram indexes valid? (all must be t) ==="
docker compose exec -T postgres psql -U ultratorrent -d ultratorrent -tAc \
"SELECT c.relname || '=' || i.indisvalid FROM pg_class c
JOIN pg_index i ON i.indexrelid = c.oid WHERE c.relname LIKE '%trgm%';"
echo -e "\n=== Latest backup ==="
ls -lht /mnt/backup/ultratorrent-*.dump 2>/dev/null | head -1 || echo "NO BACKUP FOUND"

Resolución de problemas
Si la rutina saca algo a la luz, la solución casi seguro está en Resolución de problemas. Enlaces rápidos:
- El backend no arranca
- rTorrent se reinicia
- Nada se descarga
- Un escaneo nunca termina
- Trabajos atascados en running
Consejos
- Anota el
RestartCountcada semana. El número absoluto no dice nada; la tendencia es toda la señal. - Actualiza con frecuencia, en pasos pequeños. La mayoría de los incidentes de esta documentación se arreglaron en algún lanzamiento. Mantenerte al día es la forma más barata de mantenimiento que existe.
- Vuelve a correr los escaneos interrumpidos después de cada actualización. El reinicio los mató.
Preguntas frecuentes
¿Cada cuánto debo actualizar? Mensual es una buena cadencia. Muchos de los modos de fallo documentados en este sitio están arreglados en builds posteriores — correr código viejo es quedarte con los bugs viejos.
¿Necesito correr VACUUM a mano?
Normalmente no — el autovacuum se encarga. Corre ANALYZE después de una importación
grande para que el planificador tenga estadísticas frescas.
¿Es seguro reiniciar el backend como mantenimiento rutinario? Es seguro, pero interrumpe los trabajos en vuelo. Se reconcilian (se marcan fallidos) al arranque, no se reanudan. Reinicia cuando no haya nada escaneando.
¿Por qué mi RestartCount está alto pero nada parece mal?
Porque restart: unless-stopped te está escondiendo un bucle de fallos. Si es rTorrent,
eso es el bug de fallo de 0.9.8 y depende de la carga — ya se te quedó chiquito el motor.
¿Debo podar las imágenes de Docker?
Sí — docker system prune -f y docker builder prune -f son seguros. Nunca
añadas --volumes.
Lista de verificación
Diario
-
docker compose ps— todo saludable - No hay errores nuevos en el log del backend
- Las descargas se están moviendo
Semanal
- El espacio en disco está bien
- El
RestartCountno está subiendo - No hay trabajos atascados en
running - No hay descargas fallidas sin explicación
- El backup corrió de verdad (revisa la fecha y el tamaño)
- Torrents muertos / de 0 seeders podados
Mensual
- Actualizado (con un backup tomado primero)
-
/api/system/versionconfirma que el commit nuevo está corriendo - Log de auditoría revisado (inicios de sesión fallidos, borrados, cambios de rol)
-
ANALYZEejecutado; los índices de trigramas siguen válidos - Simulacro de restauración corrido — el 2FA y la prueba de un indexador pasaron
- Cada indexador tiene un
minSeeders
Trimestral
- Secretos JWT rotados
- Usuarios y roles revisados
- Exposición revisada de nuevo (no hay puertos del motor publicados)
- El motor sigue siendo apropiado para tu conteo de torrents
Ver también
- Actualizar
- Backup y restauración — especialmente el simulacro de restauración
- Resolución de problemas
- Rendimiento
- Seguridad
- Perfiles de configuración
- Auditoría · Sistema