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-authApply:
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: 80Create 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: 8188Apply each:
kubectl apply -f comfyui-frontend.yaml
kubectl apply -f comfyui-worker.yamlCreate 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.pyYou’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!