Files
fn_registry/python/functions/infra/comfyui_ensure_server.md
T
egutierrez 68f0ce0dae feat(infra): auto-commit con 3 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-24 11:45:31 +02:00

6.2 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
comfyui_ensure_server function py infra 1.0.0 impure def comfyui_ensure_server(*, port: int = 8188, lowvram: bool | None = None, health_timeout: int = 60, comfyui_dir: str = '~/ComfyUI', unit_name: str = 'comfyui', runner=None) -> dict Garantiza que ComfyUI corre como servicio systemd-user resiliente y sano. Genera/instala el unit systemd-user comfyui.service (ExecStart con el venv de ComfyUI + main.py --port, anadiendo --lowvram si lowvram=True o autodetectando GPUs <= 8 GB; Restart=always — NO on-failure; WantedBy=default.target), hace daemon-reload + enable + start, y comprueba la salud via GET /system_stats (2xx) con timeout. Idempotente: si el servicio ya esta gestionado por systemd, activo y respondiendo, no toca nada. Migracion limpia: si ComfyUI ya corre a mano (puerto ocupado por un proceso main.py que systemd NO gestiona), lo para con SIGTERM (nunca SIGKILL) y lo levanta via systemd. Solo stdlib (subprocess, urllib, os, signal, time, re). No lanza excepciones: devuelve un dict de estado.
comfyui
systemd
service
server
resilient
ml
healthcheck
infra
false error_go_core
os
re
signal
subprocess
time
urllib.request
name desc
port puerto HTTP del backend ComfyUI; tambien el que escribe en el unit (--port) y el que sondea el health check (default 8188)
name desc
lowvram True/False fuerza/omite el flag --lowvram en ExecStart; None autodetecta por VRAM (GPUs con <= 8200 MiB -> True). Recomendado True en GPUs de 8 GB para modelos grandes (Flux, video)
name desc
health_timeout segundos maximos sondeando GET /system_stats tras arrancar el servicio antes de declararlo no-sano (default 60)
name desc
comfyui_dir raiz de la instalacion de ComfyUI; debe contener .venv/bin/python y main.py (default ~/ComfyUI, se expande y normaliza a absoluto)
name desc
unit_name nombre del unit systemd-user (sin .service); el archivo va a ~/.config/systemd/user/<unit_name>.service (default 'comfyui')
name desc
runner callable(cmd: list) -> CompletedProcess inyectable para tests; default ejecuta subprocess.run capturando salida
dict con ok (bool: servicio activo y sano), active (ActiveState del unit: active|inactive|failed), port, health (bool: /system_stats respondio 2xx), error (str|None), lowvram (bool aplicado), unit_path (ruta del .service escrito), migrated (bool: paro un ComfyUI a mano para migrar a systemd), reloaded (bool: hubo daemon-reload), idempotent (bool: ya estaba activo+sano y no se toco nada) true
_detect_lowvram aplica el umbral de 8 GB (8192/8200 -> True, 8201/24564/None -> False)
_render_unit incluye Restart=always, WantedBy=default.target y nunca on-failure; anade --lowvram solo cuando corresponde
error claro si falta el venv python en comfyui_dir
idempotente: si is-active=active y /system_stats sano, no llama a start
arranque fresco: escribe el unit, daemon-reload + enable + start y espera salud
lowvram=False omite el flag --lowvram en el unit escrito
python/functions/infra/comfyui_ensure_server_test.py python/functions/infra/comfyui_ensure_server.py

Ejemplo

import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from infra.comfyui_ensure_server import comfyui_ensure_server

# Deja ComfyUI corriendo como servicio systemd-user, sano y con --lowvram
# autodetectado en GPUs de 8 GB. Idempotente: relanzarla no rompe nada.
res = comfyui_ensure_server(port=8188, lowvram=True)
print(res)
# {'ok': True, 'active': 'active', 'port': 8188, 'health': True, 'error': None,
#  'lowvram': True, 'unit_path': '/home/enmanuel/.config/systemd/user/comfyui.service',
#  'migrated': True, 'reloaded': True, 'idempotent': False}

CLI directa (despacha por el venv del registry):

python/.venv/bin/python3 python/functions/infra/comfyui_ensure_server.py --port=8188 --lowvram

El usuario lo gestiona despues con systemd-user normal:

systemctl --user status comfyui      # estado + ultimos logs
systemctl --user restart comfyui     # reiniciar (la salud vuelve verde sola)
systemctl --user stop comfyui        # parar
systemctl --user disable --now comfyui   # revertir: para y deshabilita el arranque automatico
journalctl --user -u comfyui -n 50   # diagnosticar fallos de arranque

Cuando usarla

Usala cuando necesites que ComfyUI este garantizado arriba y sano antes de encolar workflows (txt2img, video, 3D), o para convertir el ComfyUI que hoy se relanza a mano en un servicio que arranca solo al boot y se reinicia si cae (gap del roadmap 0064). Es el primer paso del grupo comfyui: dejar el backend disponible; despues vienen comfyui_build_*_workflow + comfyui_submit_workflow.

Gotchas

  • systemd-user requiere linger para sobrevivir al cierre de sesion / arrancar al boot: loginctl enable-linger $USER. Sin linger el unit solo vive mientras hay sesion activa. Si enable falla por esto, el dict lo dice en error.
  • Migracion limpia con SIGTERM, nunca SIGKILL: si ComfyUI ya corre a mano ocupando el puerto, la funcion lo para con SIGTERM y espera a que libere el bind (hasta ~25 s) antes de arrancar el servicio. Si el puerto lo ocupa un proceso que NO es ComfyUI (cmdline sin main.py), NO lo toca y devuelve error — no arranca para no duplicar el bind.
  • Cambiar los flags del unit (p.ej. lowvram) NO reinicia un servicio ya sano: la funcion reescribe el .service y hace daemon-reload, pero si el servicio ya esta active+healthy no lo reinicia para no interrumpir. Para aplicar flags nuevos: systemctl --user restart comfyui.
  • Carga la GPU al arrancar: levantar ComfyUI reserva VRAM. En una GPU de 8 GB compartida, evita lanzarlo mientras otra tarea pesada usa la GPU.
  • Restart=always (no on-failure): un systemctl --user stop limpio es exit success; con on-failure el servicio reviviria solo tras crash. Para pararlo de verdad usa stop (no restart) o disable --now.
  • El health check es GET http://127.0.0.1:<port>/system_stats y espera 2xx; solo loopback.