Files

8.2 KiB

Remote ComfyUI Server — Connectivity & Diagnostics

This skill assumes ComfyUI is running locally on 127.0.0.1:8188 by default. When the ComfyUI server lives on another machine (LAN, headless GPU box, Proxmox LXC with passthrough, etc.), follow this guide.

Quick Checklist

  1. ComfyUI running with --listen 0.0.0.0 on the remote host
  2. Firewall open for port 8188 (or whatever custom port)
  3. Hermes can reach it via curl http://REMOTE:8188/system_stats
  4. Use --host http://REMOTE:PORT on every script invocation (or set $COMFYUI_HOST)
  5. If curl fails, SSH into the remote host to diagnose and restart (see SSH-based diagnostics)

SSH-based Remote Diagnostics and Remediation

When the remote ComfyUI server is unreachable on its HTTP port but you have SSH access to the host, SSH directly in to diagnose and fix. This is common when the user manages headless GPU boxes (Proxmox LXCs, dedicated render servers, etc.) and wants Hermes to handle restarts.

Prerequisites in the Hermes container

  • sshpass is needed for non-interactive password auth. If missing:
    # This Hermes container may not have apt-write access
    pip install --user sshpass 2>/dev/null || echo "Must install sshpass on the host manually"
    
  • If sshpass cannot be installed, use Python pexpect instead:
    pip install pexpect
    
    ...or ask the user for the correct username if root/n8n both fail.

One-shot SSH diagnostic (safe for terminal tool — no PTY tricks needed)

# Requires sshpass installed
sshpass -p 'PASSWORD' ssh -o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  '[email protected]' \
  'n8n' \
  'echo ===CONNECTED===; nvidia-smi; echo ===DONE==='

If password is rejected, STOP. Do not loop. Ask the user:

"SSH password rejected for user X on 10.0.0.202. What is the correct username and password?"

What to check/fix once SSH'd in

Command What it tells you
nvidia-smi GPU + driver status
ps aux | grep -i comfy Is ComfyUI running?
curl -s http://127.0.0.1:8188/system_stats Is it responding locally?
ss -tlnp | grep 8188 Is it listening on 0.0.0.0 or just 127.0.0.1?
ufw status | grep 8188 or iptables -L | grep 8188 Is the firewall blocking?

Common fixes

# ComfyUI not running → start it with LAN binding
comfy launch -- --listen 0.0.0.0 --port 8188 &

# Or if launched manually, relaunch:
cd ~/comfy/ComfyUI  # or wherever it's installed
python main.py --listen 0.0.0.0 --port 8188 &

# Firewall blocking → open it
ufw allow 8188/tcp
# or
iptables -A INPUT -p tcp --dport 8188 -j ACCEPT

# GPU driver issue (e.g. after host kernel update)
nvidia-smi  # check for driver mismatch
# If missing, reinstall driver on the host, NOT in the LXC

Hermes-side SSH config (one-time setup)

Store host info so future sessions can SSH without re-configuring:

mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat > ~/.ssh/config <<EOF
Host n8n
    HostName 10.0.0.202
    User USERNAME
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    IdentitiesOnly no
EOF
chmod 600 ~/.ssh/config

Important: Do not PTY-loop (terminal tool)

When sshpass is unavailable, do NOT write Python PTY scripts that call os.setsid() inside the terminal tool — this is permission-denied inside unprivileged Proxmox LXCs.

Instead use execute_code with pty.fork() — the sandbox allows the fork but the terminal tool does not. See references/remote-manual-update.md for the reusable ssh_cmd() recipe. That reference also covers:

  • Updating a manual git clone install (no comfy CLI available)
  • Safely restarting the server when nohup is rejected by terminal
  • The model-directory pitfall (CheckpointLoaderSimple vs diffusion_models)
  • The version-file staleness pitfall (comfyui_version.py)

If neither sshpass/pexpect nor execute_code + pty.fork() works, fallback is asking the user for credentials or to run the command themselves.


From Hermes (this container)

# Test 1: Is the host alive at all?
ping -c 1 10.0.0.202

# Test 2: Is port 8188 open?
python3 -c "import socket; s=socket.socket(); s.settimeout(3); s.connect(('10.0.0.202', 8188)); print('open')" 2>/dev/null || echo "closed/unreachable"

# Test 3: Does it speak HTTP?
curl -s --max-time 5 http://10.0.0.202:8188/system_stats | head -c 100

# Test 4: Wrong port? Scan common ComfyUI ports
for port in 8188 8080 3000 5000 7860 9000; do
  python3 -c "import socket; s=socket.socket(); s.settimeout(1); s.connect(('10.0.0.202', $port)); print('$port open')" 2>/dev/null
done

Likely causes & fixes

Symptom Cause Fix on remote host
Connection refused ComfyUI listening on 127.0.0.1 only comfy launch -- --listen 0.0.0.0 --port 8188
No route to host Firewall / network segment blocking ufw allow 8188/tcp or adjust Proxmox firewall rules
Connection timed out ComfyUI not running at all ps aux | grep -i comfy then start it
Wrong port open ComfyUI launched on a non-default port Re-launch with --port 8188 or note the actual port
Works from remote shell but not Hermes Proxmox LXC bridge / VLAN isolation Check CT firewall rules; ensure both CTs share bridge
Password rejected via sshpass Wrong username or password, or password-only SSH disabled Clarify user/password with user; do not loop, ask once

Credential Ambiguity — Pitfall

When the user says something like:

"SSH n8n - passw0rd"

They may mean any of:

  • Host alias = n8n, password = passw0rd, user = default (root)
  • Host alias = n8n, user = n8n, password = passw0rd
  • Host IP 10.0.0.202, user = n8n, password = passw0rd

Best practice: Immediately write the SSH config with the most likely translation, then run a minimal connectivity probe before attempting diagnosis:

sshpass -p 'passw0rd' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
  n8n 'echo ok'  # or 'USER@HOST'

If this fails with "Permission denied", stop and ask the user for the correct username and password rather than writing elaborate PTY-based workarounds. Time spent writing Python PTY scripts is better spent asking for clarified credentials.

Remote Execution Examples

Single image generation

python3 scripts/run_workflow.py \
  --workflow workflows/flux_dev_txt2img.json \
  --args '{"prompt": "cyberpunk city at night", "seed": -1, "steps": 30}' \
  --host http://10.0.0.202:8188 \
  --output-dir ./outputs

Batch with parallel sweeps

python3 scripts/run_batch.py \
  --workflow workflows/sdxl.json \
  --args '{"prompt": "abstract art"}' \
  --count 8 --randomize-seed --parallel 4 \
  --host http://10.0.0.202:8188 \
  --output-dir ./outputs/batch

img2img with local source image uploaded to remote

python3 scripts/run_workflow.py \
  --workflow workflows/sdxl_img2img.json \
  --input-image image=./photo.png \
  --args '{"prompt": "oil painting style", "denoise": 0.65}' \
  --host http://10.0.0.202:8188 \
  --output-dir ./outputs

Real-time WebSocket progress monitoring

python3 scripts/run_workflow.py \
  --workflow workflows/wan_t2v.json \
  --args '{"prompt": "a cat dancing", "frames": 81}' \
  --host http://10.0.0.202:8188 \
  --ws \
  --output-dir ./outputs

Environment Variable

Set once in your shell profile to avoid typing --host every time:

export COMFYUI_HOST="http://10.0.0.202:8188"

All scripts in this skill respect $COMFYUI_HOST when --host is not explicitly passed.

Proxmox LXC Specifics

If the remote ComfyUI is in an unprivileged Proxmox LXC:

  • Ensure the LXC has features: nesting=1 if running comfy-cli inside it
  • GPU passthrough requires lxc.cgroup2.devices.allow entries for the NVIDIA/AMD card
  • Bridge networking (net0: bridge=vmbr0) should make it LAN-reachable from other LXCs on the same bridge
  • If Hermes is in a different LXC that cannot reach 10.0.0.202, check:
    • Proxmox host-level firewall rules
    • Whether both CTs share the same bridge (vmbr0 vs vmbr1)
    • The LXC net0 IP assignment (DHCP vs static)