Below is a succinct guide showing how to set up:
- A uv‑backed virtual environment on Linux
- A Docker build for ComfyUI
- RabbitMQ with a KEDA ScaledObject for auto-scaling workers
- A ComfyUI frontend Deployment and ComfyUI worker StatefulSet
…plus a short Python script using the “queue_and_forget” approach.
sudo apt-get update
sudo apt-get install -y python3 python3-pip python3-venv git
# Create a workspace and cd into it
mkdir ~/comfyui_workspace
cd ~/comfyui_workspace
# Create a virtual environment with uv (if uv is available)
uv venv --seed --python 3.12
source .venv/bin/activate
# Install required dependencies
uv pip install --upgrade pip setuptools wheel
uv pip install aiohttp
uv pip install "comfyui[withtorch]@git+https://github.com/hiddenswitch/ComfyUI.git"
Build the image:
docker build -t example.samhodge.com/comfyui:latest .
Create a file, for instance, rabbitmq-keda.yaml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rabbitmq
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: rabbitmq
template:
metadata:
labels:
app: rabbitmq
spec:
containers:
- name: rabbitmq
image: rabbitmq:3-management
ports:
- containerPort: 5672 # AMQP
- containerPort: 15672 # Management
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
namespace: default
spec:
selector:
app: rabbitmq
ports:
- name: amqp
port: 5672
targetPort: 5672
- name: management
port: 15672
targetPort: 15672
# KEDA TriggerAuthentication referencing secret with RabbitMQ connection
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-trigger-auth
namespace: default
spec:
# In a real deployment, you'll have a Secret with this key
secretTargetRef:
- parameter: host
name: rabbitmq-conn-secret
key: uri # e.g., "amqp://guest:[email protected]"
# KEDA ScaledObject automatically scales comfyui-worker based on queue length
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: comfyui-scaledobject
namespace: default
spec:
scaleTargetRef:
name: comfyui-worker # must match the metadata.name of your StatefulSet or Deployment
minReplicaCount: 1
maxReplicaCount: 5
triggers:
- type: rabbitmq
metadata:
queueName: comfyui-queue # name of queue used by your distributed comfy
hostFromEnv: host
authenticationRef:
name: rabbitmq-trigger-auth
Apply:
kubectl apply -f rabbitmq-keda.yaml
(Make sure you also create a Secret named rabbitmq-conn-secret
with key uri
containing your RabbitMQ connection string, or adjust the above references accordingly.)
Create comfyui-frontend.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: comfyui-frontend
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: comfyui-frontend
template:
metadata:
labels:
app: comfyui-frontend
spec:
containers:
- name: comfyui-frontend
image: example.samhodge.com/comfyui:latest
command: ["/bin/sh", "-c"]
args:
- |
comfyui \
--distributed-queue-frontend \
--distributed-queue-connection-uri=amqp://guest:[email protected] \
--external-address=https://example.samhodge.com
ports:
- containerPort: 8188
---
apiVersion: v1
kind: Service
metadata:
name: comfyui-frontend
namespace: default
spec:
selector:
app: comfyui-frontend
ports:
- name: http
port: 80
targetPort: 8188
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: comfyui-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: example.samhodge.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: comfyui-frontend
port:
number: 80
Create comfyui-worker.yaml:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: comfyui-worker
namespace: default
spec:
serviceName: "comfyui-worker"
replicas: 1
selector:
matchLabels:
app: comfyui-worker
template:
metadata:
labels:
app: comfyui-worker
spec:
containers:
- name: comfyui-worker
image: example.samhodge.com/comfyui:latest
command: ["/bin/sh", "-c"]
args:
- |
comfyui-worker \
--distributed-queue-connection-uri=amqp://guest:[email protected] \
--external-address=https://example.samhodge.com
ports:
- containerPort: 8188
Apply each:
kubectl apply -f comfyui-frontend.yaml
kubectl apply -f comfyui-worker.yaml
Create queue_prompt_example.py:
import asyncio
import uuid
from comfy.client.aio_client import AsyncRemoteComfyClient
from comfy.api.components.schema.prompt import PromptDict
# you'll have to fill this in yourself
ADDRESS="http://ingress:8188"
async def main():
client = AsyncRemoteComfyClient(server_address=ADDRESS, client_id=str(uuid.uuid4()))
sample_prompt: PromptDict = {
"1": {
"class_type": "IntRequestParameter",
"inputs": {
"frame": 10
}
}
# ... additional nodes ...
}
# Fire-and-forget approach:
task_id = await client.queue_and_forget_prompt_api(sample_prompt)
print(f"Prompt queued. Task ID: {task_id}")
if __name__ == "__main__":
asyncio.run(main())
Running:
python queue_prompt_example.py
You’ll see:
Prompt queued. Task ID: ...
- uv venv: fast package install & environment setup on Linux.
- Docker build: includes ComfyUI.
- RabbitMQ + KEDA: auto-scales the ComfyUI worker based on queue traffic.
- Frontend (ingress) & Worker (stateful) for distributed ComfyUI.
- Fire‑and‑Forget script: shows how to enqueue a prompt quickly without waiting for image bytes.
Enjoy your distributed, auto‑scaling ComfyUI setup!