容器化部署 ComfyUI
本指南详细阐述了将 ComfyUI 封装成 API 并使其能够直接在 Docker 容器环境中运行的方法,同时也介绍了如何在 共绩算力 上运用 ComfyUI 部署包含自定义的 stable diffusion 模型的工作流。
我们基于本教程开源了一套前后端分离的 Comfy UI 服务。
具有完整的 Docker&Serverless 化部署方案,您可以参考使用。
https://github.com/nexmoe/serverless-comfyui

本教程对应开源库中的 backend 文件夹
无论你选择什么样的 stable diffusion 推理服务、模型或扩展,基本流程如下:
- 选择 Docker 基础镜像用于构建我们自己的自定义镜像
- 将所需的模型和扩展复制到 Docker 镜像中
- 将新镜像推送到容器仓库
- 将镜像部署为 共绩算力 服务
- Docker
- NVIDIA GPU(当前演示工作流需要 12G 显存以上)
- 足够的磁盘空间(100G~200G)用于存储模型
这是当前项目的完整结构,所有文件、模型、自定义节点等都应该在对应的位置。
.├── Dockerfile├── checkpoints│ └── dreamshaperXL_sfwV2TurboDPMSDE.safetensors├── controlnet│ ├── sai_xl_canny_256lora.safetensors│ └── sai_xl_depth_256lora.safetensors├── custom_nodes│ ├── ComfyUI-Custom-Scripts│ ├── ComfyUI-WD14-Tagger│ ├── ComfyUI_Comfyroll_CustomNodes│ ├── comfyui-art-venture│ └── comfyui_controlnet_aux├── docker-compose.yml├── loras│ └── StudioGhibli.Redmond-StdGBRRedmAF-StudioGhibli.safetensors├── provisioning.sh // 自定义脚本└── sanhua.json // 工作流
选择 Docker 基础镜像
Section titled “选择 Docker 基础镜像”找到一个 ComfyUI 的 Docker 基础镜像。以下是我们验证过可以在 共绩算力 上运行的镜像,我们将在 Dockfile 里作为基础镜像使用:
- Git 仓库:https://github.com/ai-dock/comfyui
- Docker 镜像:ghcr.io/ai-dock/comfyui:v2-rocm-6.0-runtime-22.04-v0.2.7
- 模型目录:
/opt/ComfyUI/models
- 自定义节点目录:
/opt/ComfyUI/custom_nodes/
下载模型和扩展
Section titled “下载模型和扩展”-
在我们的示例中,我们将使用下面 4 个模型文件,请自行下载,保存到项目结构中对应目录
- https://civitai.com/models/112902?modelVersionId=341981
- https://huggingface.co/lllyasviel/sd_control_collection/blob/main/sai_xl_canny_256lora.safetensors
- https://huggingface.co/lllyasviel/sd_control_collection/blob/main/sai_xl_depth_256lora.safetensors
- https://huggingface.co/artificialguybr/StudioGhibli.Redmond-V2/blob/main/StudioGhibli.Redmond-StdGBRRedmAF-StudioGhibli.safetensors
-
根据项目结构去 Github 搜索名称并下载安装准备对应的 5 个 custom_nodes
创建 Dockerfile
Section titled “创建 Dockerfile”1. 配置 Dockerfile
Section titled “1. 配置 Dockerfile”创建一个名为 Dockerfile
的新文件,并在你喜欢的文本编辑器中打开。
此时,你的目录结构应该完整包含所需的文件,包含:
- checkpoints、controlnet、loras 共 3 模型目录,4 个模型文件。
- custom_nodes 工作流使用的自定义节点
将以下内容复制到你的 Dockerfile 中:
FROM ghcr.io/ai-dock/comfyui:v2-cuda-12.1.1-base-22.04-v0.2.7
ENV WEB_ENABLE_AUTH=false
ENV MODEL_DIR=/opt/ComfyUI/modelsCOPY checkpoints/dreamshaperXL_sfwV2TurboDPMSDE.safetensors ${MODEL_DIR}/checkpoints/dreamshaperXL_sfwV2TurboDPMSDE.safetensorsCOPY controlnet/sai_xl_canny_256lora.safetensors ${MODEL_DIR}/controlnet/sai_xl_canny_256lora.safetensorsCOPY controlnet/sai_xl_depth_256lora.safetensors ${MODEL_DIR}/controlnet/sai_xl_depth_256lora.safetensorsCOPY loras/StudioGhibli.Redmond-StdGBRRedmAF-StudioGhibli.safetensors ${MODEL_DIR}/loras/StudioGhibli.Redmond-StdGBRRedmAF-StudioGhibli.safetensors
ENV NODE_DIR=/opt/ComfyUI/custom_nodesCOPY custom_nodes/ComfyUI_Comfyroll_CustomNodes ${NODE_DIR}/ComfyUI_Comfyroll_CustomNodesCOPY custom_nodes/comfyui_controlnet_aux ${NODE_DIR}/comfyui_controlnet_auxCOPY custom_nodes/comfyui-art-venture ${NODE_DIR}/comfyui-art-ventureCOPY custom_nodes/ComfyUI-Custom-Scripts ${NODE_DIR}/ComfyUI-Custom-ScriptsCOPY custom_nodes/ComfyUI-WD14-Tagger ${NODE_DIR}/ComfyUI-WD14-Tagger
COPY provisioning.sh /opt/ai-dock/bin/provisioning.sh
ADD https://github.com/SaladTechnologies/comfyui-api/releases/download/1.6.1/comfyui-api .RUN chmod +x comfyui-api
COPY sanhua.json .ENV WARMUP_PROMPT_FILE=sanhua.json
CMD ["./comfyui-api"]
注意:我们在镜像中包含了一个简单的包装器 comfyui-api,以便更容易获取生成的图像。
为什么?
ComfyUI 将提示词放入队列中,然后最终将图像保存到本地文件系统。这使得它在像 共绩算力 这样的弹性无状态环境中难以使用。comfyui-api 扩展了 ComfyUI 的 /prompt
API,允许在响应体中接收生成的图像,或将完整的图像提交到提供的 webhook url。
其它特性?
comfyui-api 全面支持 ComfyUI 的/prompt API,能够执行任何 ComfyUI 工作流,并以无状态 API 设计实现水平扩展以处理更多请求。它提供 Swagger 文档交互(位于/docs),直接返回 base64 编码图片或通过 webhook 发送完成的图片,接受 base64 编码字符串或图片 URL 提交图片,简化了图像到图像的工作流程。启动时可配置预热工作流以加载模型并准备好接收请求,返回图片格式支持 PNG、JPEG 或 WebP,默认为 PNG。此外,它还提供/health 和/ready 探针检查服务器健康状况和准备情况,动态挂载工作流端点,允许用户自带模型和扩展
2. 定义 provisioning.sh
Section titled “2. 定义 provisioning.sh”在 provisioning.sh 中定义依赖安装脚本。你也可以定义任何内容。
printf "=========================================================\n"
pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
cd /opt/ComfyUI/custom_nodes/comfyui_controlnet_auxpip install -r requirements.txt
cd /opt/ComfyUI/custom_nodes/ComfyUI-WD14-Taggerpip install -r requirements.txt
printf "=========================================================\n"
3. 准备工作流文件(可选)
Section titled “3. 准备工作流文件(可选)”在 Dockerfile 所在的目录中保存一个 API 格式的 workflow.json(项目结构中的 sanhua.json)文件。这个文件将用于在启动服务器之前预热服务器。你可以使用 ComfyUI 网页界面创建 workflow,然后以 API 格式保存它。
如果没有,需要修改 Dockerfile 去除相关内容。
构建和测试 Docker 镜像
Section titled “构建和测试 Docker 镜像”1. 构建镜像
Section titled “1. 构建镜像”构建 docker 镜像。你应该根据自己的情况更改指定的版本标签。
docker build -t gongji/comfyui:0.1 .
2. 本地测试
Section titled “2. 本地测试”在本地运行 docker 镜像以确认它按预期工作:
docker run -it --rm --gpus all -p 3000:3000 -p 8188:8188 --name comfyui gongji/comfyui:0.1
在本地使用时,我们将暴露端口 3000(api 接口)和端口 8188(让我们可以在本地访问 web ui)。
部署到共绩算力(弹性算力平台)后,你的应用程序应该通过 API 与其交互,而不是通过浏览器 web ui。
-
在浏览器中访问
http://localhost:8188
。 -
点击 “Queue Prompt” 生成图像。
-
通过设置菜单启用开发者模式选项。你可以在菜单中看到一个新选项 “Save (API Format)
-
点击 “Save(API Format)” 按钮并保存。你会得到一个名为
workflow_api.json
的文件,其中包含 ComfyUI 再次运行该提示所需的所有内容。
注意:你可能注意到这种提示格式不太直观,但它确实包含了 ComfyUI 使用的节点和连接。根据经验,ComfyUI web ui 是设计提示的最佳方式,而不是试图从头开始创建这样的工作流 json 文件。
3. API 测试
Section titled “3. API 测试”使用 Postman 或任何你选择的 http 请求工具,将 prompt 提交到端口 3000 上的 API 接口。
你可以通过 http://localhost:3000/docs

向 http://localhost:3000/prompt
发送 POST 请求,JSON 请求体如下。其中“prompt”的值是我们之前创建的 workflow_api.json
。
{ "prompt": { ... }}
几秒钟后,你应该收到类似这样的响应:
{ "id": "random-uuid", "prompt": { ... }, "images": ["base64encodedimage"]}
将 base64 编码的字符串解码为图像。你可以:
- 使用免费的浏览器工具,如 base64-to-image-converter
推送和部署 Docker 镜像到生产
Section titled “推送和部署 Docker 镜像到生产”1. 推送镜像到共绩算力
Section titled “1. 推送镜像到共绩算力”这一步会将上一步中自定义的镜像上传到我们的镜像仓库服务中。请参考文档进行:https://www.gongjiyun.com/docs/docker/harbor.html
2. 部署配置
Section titled “2. 部署配置”下面已经配置好的 docker-compose.yml 文件,相应的镜像已上传到共绩算力镜像仓库中,可以直接用于发布任务。
对于自己自定义的 docker-compose.yml,请先在本地使用 docker compose up
运行起来,来检查服务是否正常。
version: '3.9'services: comfyui: image: harbor.suanleme.cn/xuwenzheng/nex-comfy:sanhua0.5 ports: - "3008:3000" - "8189:8180" labels: # 第一个转发端口 - suanleme_0.http.port=3000 - suanleme_0.http.prefix=nexapi # 第二个转发端口 - suanleme_1.http.port=8188 - suanleme_1.http.prefix=nexui deploy: resources: reservations: devices: - driver: nvidia # 使用 NVIDIA GPU 驱动 count: 1 # 预留的 GPU 数量 capabilities: [ gpu ] # 指定 GPU 功能
3. 部署服务
Section titled “3. 部署服务”去往共绩算力控制台 https://dockerweb.gongjiyun.com

填写 Docker Compose 和基本信息

尽管我们所选用的基础镜像以 CUDA 12.1.1 为基础,但此镜像依旧能够选择更高的 CUDA 版本。
建议选择节点数量在 3 个以上。在显卡方面,推荐使用 3090,当前任务最低要求为显存在 12G 以上的显卡。

当前镜像的 API 服务已完成对 health check 接口的封装,可供平台检测服务的健康状态。其修改路径为对应的“/health”。该 API 服务对应 3000 端口。

等待节点部署

节点分配完成后,可以通过回传链接访问服务

链接 https://hadoop.nexmoe.com 是基于此工作流开发的网页应用,您可以在线体验。
