ComfyUI
Deploy ComfyUI on a Spheron GPU instance using Docker. ComfyUI provides a browser-based node editor for building image generation workflows, plus a JSON API for programmatic access.
Recommended hardware
| Workload | Min VRAM | Recommended GPU | Instance Type |
|---|---|---|---|
| SD 1.5 workflows | 6 GB | Any 6 GB+ GPU | Spot |
| SDXL workflows | 10 GB | RTX 4090 (24 GB) | Spot or Dedicated |
| FLUX.1 workflows | 16 GB | RTX 4090 (24 GB) | Dedicated |
| Large batch generation | 40 GB | A100 40/80 GB | Dedicated |
Prerequisites
- A running Spheron GPU instance (see Instance Types)
- SSH access to the instance
- A model checkpoint file (
.safetensorsor.ckpt) for the workflow you want to run
Manual setup
Use these steps to set up the server manually after SSH-ing into your instance. This works on any provider regardless of cloud-init support.
Step 1: Connect to your instance
ssh <user>@<ipAddress>Replace <user> with the username shown in the instance details panel (e.g., ubuntu for Spheron AI instances) and <ipAddress> with your instance's public IP.
Step 2: Install Docker and NVIDIA container toolkit
sudo apt-get update -y
sudo apt-get install -y docker.io nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockerStep 3: Create model and output directories
sudo mkdir -p /opt/comfyui/models /opt/comfyui/output /opt/comfyui/custom_nodesPlace model checkpoints (.safetensors, .ckpt) in /opt/comfyui/models/checkpoints/ before or after startup. ComfyUI auto-detects them.
Step 4: Start ComfyUI
docker run -d \
--gpus all \
--name comfyui \
-p 8188:8188 \
-v /opt/comfyui/models:/root/ComfyUI/models \
-v /opt/comfyui/output:/root/ComfyUI/output \
-v /opt/comfyui/custom_nodes:/root/ComfyUI/custom_nodes \
yanwk/comfyui-boot:cu128-slimVerify it is running:
docker ps
docker logs -f comfyuiAccessing the server
SSH tunnel (recommended)
ssh -L 8188:localhost:8188 <user>@<ipAddress>Then open http://localhost:8188 in your browser.
Programmatic workflow API
ComfyUI exposes a POST /prompt endpoint for running workflows programmatically. Use the browser UI to build and export your workflow as API JSON, then submit it via HTTP.
import requests
import uuid
# Export your workflow from ComfyUI browser UI as API format JSON
with open("workflow_api.json") as f:
import json
workflow = json.load(f)
response = requests.post(
"http://localhost:8188/prompt",
json={
"client_id": str(uuid.uuid4()),
"prompt": workflow,
},
)
response.raise_for_status()
prompt_id = response.json()["prompt_id"]
print("Prompt ID:", prompt_id)Poll for completion
import requests, time
prompt_id = "your-prompt-id"
# Terminal states per ComfyUI execution.py: "success" or "error"
TERMINAL_ERROR_STATES = {"error"}
max_retries = 300 # 5 minutes at 1-second intervals
for _ in range(max_retries):
response = requests.get(f"http://localhost:8188/history/{prompt_id}")
response.raise_for_status()
history = response.json()
if prompt_id in history:
job = history[prompt_id]
status = job.get("status")
if isinstance(status, dict):
status_str = status.get("status_str")
elif status is not None:
print(f"Warning: unexpected status format (type={type(status).__name__!r}), continuing to poll...")
status_str = None
else:
status_str = None
if status_str == "success":
outputs = job.get("outputs", {})
print("Generation complete:", outputs)
break
elif status_str in TERMINAL_ERROR_STATES:
# Extract the exception message from the execution_error entry in messages
messages = status.get("messages", []) if isinstance(status, dict) else []
error_detail = next(
(msg[1] for msg in messages if isinstance(msg, (list, tuple)) and msg[0] == "execution_error"),
None,
)
detail_str = (
f": {error_detail.get('exception_message', '')}"
if isinstance(error_detail, dict)
else ""
)
raise RuntimeError(f"Generation failed with status '{status_str}'{detail_str}")
elif status_str is not None:
# Unknown status: log a warning and keep polling
print(f"Warning: unknown status '{status_str}', continuing to poll...")
time.sleep(1)
else:
raise TimeoutError(f"Generation did not complete within {max_retries} seconds")Check container logs
docker logs -f comfyuiCloud-init startup script (optional)
If your provider supports cloud-init, you can paste this into the Startup Script field when deploying to automate the setup above. It starts ComfyUI via the yanwk/comfyui-boot:cu128-slim Docker image (CUDA 12.8), a minimal install that includes ComfyUI and ComfyUI-Manager. Install additional custom nodes through the ComfyUI-Manager interface after startup.
#cloud-config
runcmd:
- apt-get update -y
- apt-get install -y docker.io nvidia-container-toolkit
- nvidia-ctk runtime configure --runtime=docker
- systemctl restart docker
- mkdir -p /opt/comfyui/models /opt/comfyui/output /opt/comfyui/custom_nodes
- |
docker run -d \
--gpus all \
--name comfyui \
-p 8188:8188 \
-v /opt/comfyui/models:/root/ComfyUI/models \
-v /opt/comfyui/output:/root/ComfyUI/output \
-v /opt/comfyui/custom_nodes:/root/ComfyUI/custom_nodes \
yanwk/comfyui-boot:cu128-slimPlace model checkpoints (.safetensors, .ckpt) in /opt/comfyui/models/checkpoints/ before or after startup.
What's next
- FLUX.1 & FLUX.2: FLUX models compatible with ComfyUI
- Stable Diffusion 3.5 & SDXL: SD models for ComfyUI workflows
- Image Generation Overview: VRAM requirements and model comparison
- Networking: SSH tunneling and port access