Deploy ComfyUI as a Serverless API for Scalable AI Image Generation
This article explains how to transform ComfyUI into a serverless API using Alibaba Cloud Function Compute, detailing the challenges of GPU resource costs, high concurrency, and usability, while providing a step‑by‑step guide, code examples, and best‑practice recommendations for building scalable AI drawing applications.
Background
ComfyUI provides a flexible, node‑based image generation workflow. Native deployments are limited by three factors: (1) high cost and scarcity of GPU resources, (2) difficulty handling high‑concurrency request bursts, and (3) a steep learning curve for integration.
Serverless Architecture
The solution packages ComfyUI in a container image and runs it on Alibaba Cloud Function Compute. An agent program embedded in the image translates incoming API calls into ComfyUI‑compatible prompts, launches the ComfyUI process, and collects progress and output. This makes the workflow stateless, asynchronous, and horizontally scalable.
Key Advantages
Simple deployment : a base ComfyUI image can be started with a single command; custom images are supported by changing the image reference.
Elastic GPU : Function Compute automatically creates or removes GPU instances based on request volume.
Pay‑per‑use billing : resources are charged per millisecond of execution.
Serverless adaptation : the agent adds async handling, concurrency control, and stateless execution.
Frontend integration : an open‑source UI renders a parameter panel from a JSON schema and can trigger concurrent image generation.
API Design
Two primary HTTP endpoints are provided: /api/run – synchronous POST that accepts a JSON prompt payload and returns the final TProgress object containing image information. /api/run/ws – WebSocket endpoint that streams intermediate progress updates.
For asynchronous execution, add the header X-Fc-Invocation-Type: Async and a unique task-id. Progress can be queried later via /api/status?id=<task-id>.
Prompt and Progress Data Structures
type TPromptNode struct {
Inputs map[string]any `json:"inputs"`
ClassType string `json:"class_type"`
Meta map[string]any `json:"_meta"`
}
type TPrompt map[string]TPromptNode
type TProgress map[string]TProgressNode
type TProgressNode struct {
Max int `json:"max"`
Value int `json:"value"`
Start int64 `json:"start"`
LastUpdated int64 `json:"last_updated"`
Images []TProgressNodeImage `json:"images"`
Results []string `json:"results,omitempty"`
}
type TProgressNodeImage struct {
Filename string `json:"filename"`
SubFolder string `json:"subfolder"`
Type string `json:"type"`
}Sample Asynchronous Curl Request
curl http://example.com/api/run -v \
-H 'X-Fc-Invocation-Type: Async' \
-H "task-id: abcdefg" \
-XPOST \
-d '{
"3": {"inputs": {"seed": 1586995582004891, "steps": 17, "cfg": 6, "sampler_name": "dpm_2", "scheduler": "karras", "denoise": 1, "model": ["33",0], "positive": ["31",0], "negative": ["32",0], "latent_image": ["5",0]}, "class_type": "KSampler", "_meta": {"title": "KSampler"}}
// ... other nodes omitted for brevity ...
}'Agent Implementation Details
The agent source resides in fc-comfyui/src/images/agent (
https://github.com/OhYee/fc-comfyui/tree/master/src/images/agent) and performs three core tasks:
Convert incoming /prompt requests into ComfyUI‑compatible calls.
Launch the ComfyUI container and forward the request.
Collect progress and image output, storing state on a mounted NAS (file system) or a custom key‑value store.
State storage is abstracted via the Store interface:
type Store interface {
// Save stores a value under a key
Save(key string, value string) error
// Load retrieves a value by key
Load(key string) (string, error)
}The default implementation ( fs.go) writes JSON progress files to a shared file system. Production deployments can replace it with database‑backed implementations (e.g., OTS, MySQL) by providing another Store implementation.
Frontend Integration
A companion UI repository ( devsapp/fc-comfyui-couple-photo) renders a parameter panel based on a JSON schema. Each panel entry is described by the following TypeScript type:
export type ComfyUIPromptEditPanel = {
type: 'image' | 'select' | 'number' | 'string' | 'group';
id?: string; // node id in the prompt
key: string; // parameter name to modify
title: string;
description?: string;
options?: string[] | string; // for select/image types
min?: number;
max?: number;
step?: number;
hidden?: boolean;
children?: ComfyUIPromptEditPanel[]; // for group type
};Special handling includes replacing a seed value of -1 with a random integer at runtime.
Configuration and Best Practices
Enable the agent by setting the environment variable USE_AGENT=1 in the Function Compute runtime.
When using the /api/run + /api/status pattern, mount a persistent storage (NAS or database) so that progress files are shared across function instances.
For high‑concurrency workloads, limit per‑instance concurrency to 1‑5 to avoid state collisions.
The provided agent code is a reference implementation; production use should harden security, add proper error handling, and adapt business logic as needed.
Alibaba Cloud Native
We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
