部署前先理解:ControlNet不是单独的绘画软件
ControlNet是Stable Diffusion生态中常用的AI绘画插件,主要用于根据姿态、线稿、深度图、边缘图等条件控制出图结果。很多用户搜索“一键部署ControlNet”,实际需要部署的是“Stable Diffusion WebUI + ControlNet插件 + 对应控制模型”的完整运行环境。Docker的价值在于把Python、CUDA依赖、插件文件和启动参数封装起来,减少本机环境冲突,适合新机部署、服务器迁移、团队统一环境和快速回滚。

在开始前建议准备三类资源:第一,已安装Docker的Linux服务器或Windows/macOS的Docker Desktop;第二,具备NVIDIA显卡的机器最好安装好显卡驱动与NVIDIA Container Toolkit;第三,准备可持久化的数据目录,用于保存模型、输出图片、插件配置和临时文件。若只是CPU体验,也能启动,但速度会明显偏慢,不建议用于正式创作。
一、确认基础环境与目录规划
先在终端执行 docker --version,确认Docker可用。使用NVIDIA显卡时,再执行 nvidia-smi 查看显卡是否被系统识别;随后执行 docker run --rm --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi 测试容器能否调用显卡。若这一步失败,通常不是ControlNet问题,而是驱动或容器运行时未配置好。
目录建议提前规划,例如创建 /opt/ai/sd-webui 作为项目根目录,下面分成 models、extensions、outputs、config 四个子目录。ControlNet相关模型可放在 models/ControlNet,Stable Diffusion基础模型可放在 models/Stable-diffusion。这样即使删除容器或升级镜像,模型和图片也不会跟着丢失。
二、选择镜像并完成拉取
部署时优先选择维护活跃、说明完整、支持WebUI和ControlNet的镜像。不同维护者的镜像名称不同,常见命名会包含 stable-diffusion-webui、controlnet、cuda 等字样。拉取前要看清三个信息:支持的CUDA版本、是否内置ControlNet插件、默认启动端口。不要盲目使用来源不明的镜像,尤其是带有未知脚本和修改版依赖的镜像。
通用拉取命令格式为:docker pull 镜像仓库/镜像名:标签。如果你使用的是项目方提供的镜像,例如 your-registry/stable-diffusion-webui-controlnet:latest,可执行 docker pull your-registry/stable-diffusion-webui-controlnet:latest。生产环境不建议长期使用latest标签,因为它会随镜像更新变化,后续排查问题更困难。更稳妥的做法是固定版本号,例如 :cuda12.1-v1.8 这类明确标签。
三、使用docker run快速启动
最小化启动可使用以下思路:将容器内WebUI端口映射到宿主机,将模型和输出目录挂载到宿主机,并允许容器访问GPU。示例命令可写成一行:docker run -d --name sd-controlnet --gpus all -p 7860:7860 -v /opt/ai/sd-webui/models:/app/stable-diffusion-webui/models -v /opt/ai/sd-webui/outputs:/app/stable-diffusion-webui/outputs -v /opt/ai/sd-webui/config:/app/stable-diffusion-webui/config your-registry/stable-diffusion-webui-controlnet:cuda12.1-v1.8。
其中 -p 7860:7860 表示把宿主机7860端口映射到容器7860端口。启动后在浏览器访问 https://服务器IP:7860 即可进入WebUI。如果7860已被占用,可以改成 -p 17860:7860,此时访问地址变为 https://服务器IP:17860。端口映射左边是宿主机端口,右边是容器端口,新手最容易把两者混淆。
四、用Compose管理更适合长期使用
如果准备长期运行,建议使用Docker Compose,便于升级、回滚和记录配置。在项目目录中新建 compose.yml,核心配置包括镜像名、容器名、端口、数据卷、GPU能力和重启策略。配置思路如下:服务名可设为 sd-controlnet,镜像指定为固定版本,端口写 "7860:7860",数据卷分别挂载models、outputs和config,重启策略使用 unless-stopped。GPU配置可使用Docker当前支持的 gpus: all。
启动命令为 docker compose up -d,查看日志使用 docker logs -f sd-controlnet,停止服务使用 docker compose down。需要注意,down 只会删除容器和网络,不会删除你挂载在宿主机的数据目录;但如果使用了未挂载的容器内部路径,容器删除后文件就可能找不回来。因此模型、插件和输出目录必须尽量外置。
五、ControlNet模型与插件目录配置
ControlNet能否正常使用,关键不只是插件安装,还要放对控制模型。常见模型文件扩展名包括 .safetensors、.pth,应放入WebUI识别的ControlNet模型目录。不同镜像路径略有差异,常见位置是 /app/stable-diffusion-webui/extensions/sd-webui-controlnet/models 或 /app/stable-diffusion-webui/models/ControlNet。如果镜像说明中指定了路径,应以镜像说明为准。
为了管理方便,可以把宿主机 /opt/ai/sd-webui/models/ControlNet 挂载到容器内ControlNet模型目录。这样新增openpose、canny、depth、lineart等控制模型时,只需把文件复制到宿主机目录,然后在WebUI中刷新模型列表。基础大模型则应放到 models/Stable-diffusion,VAE放到对应VAE目录,LoRA放到Lora目录。目录清晰后,后续迁移只需整体复制 /opt/ai/sd-webui。
六、端口、防火墙与访问范围
WebUI默认面向本机或局域网络使用,不建议直接把管理页面暴露到公网。若必须远程访问,至少应通过反向袋里、访问控制、账号认证或内网白名单限制访问范围。部署在云主机时,还要同时检查系统防火墙与云平台安全组,确保只开放必要端口。若只是个人使用,更推荐通过内网地址访问,或在服务器上使用SSH端口转发到本机浏览器。
端口冲突时,执行 docker ps 查看已有容器端口;也可以用 ss -lntp | grep 7860 查找占用进程。修改端口后需要重建容器或更新Compose配置再启动。不要在不了解含义的情况下开放过多端口,尤其是容器内的调试端口、文件服务端口和临时API端口。
七、升级、回滚与数据备份
升级镜像前先备份配置和关键目录,至少包括 models、extensions、config、outputs。升级流程建议为:记录当前镜像标签;停止容器;拉取新镜像;用相同挂载目录启动;进入WebUI检查插件和模型是否识别。若出现插件不兼容、启动报错或出图异常,可把镜像标签改回旧版本并重新启动,这就是固定版本标签的优势。
不建议直接在运行中的容器里手工改大量文件,因为这些改动难以复现。更好的方式是把需要长期保留的内容挂载到宿主机,或者通过自定义Dockerfile构建内部镜像。团队环境还应把启动参数、镜像版本、插件版本和模型清单记录下来,避免不同成员看到的界面一致但实际依赖不同。
八、常见问题排查
1. 页面打不开:先看容器是否运行,执行 docker ps;再看日志 docker logs sd-controlnet;确认端口映射是否正确,防火墙是否允许访问。
2. 显卡没有被使用:检查 nvidia-smi 和容器GPU测试命令。若容器内无法识别显卡,优先处理驱动和NVIDIA Container Toolkit,不要反复重装插件。
3. ControlNet面板存在但模型为空:多半是模型目录挂载错误,或模型文件放到了基础大模型目录。进入容器执行 docker exec -it sd-controlnet bash,检查容器内目标目录是否能看到模型文件。
4. 出图时报显存不足:可降低分辨率、批量数量和ControlNet单元数量,启用低显存参数,或选择更小的基础模型。多个ControlNet同时开启会显著增加显存压力。
5. 插件更新后无法启动:先查看最近更新记录,临时移除插件目录或回退镜像版本。插件与WebUI版本不匹配是常见原因,稳定使用时不要频繁追新。
九、实用建议与权限边界
ControlNet部署完成后,建议建立三个习惯:一是所有模型来源要可信,下载后核对文件名、大小和说明;二是生成内容要遵守平台规范和素材授权要求,不把他人作品、肖像或受保护素材用于不合规用途;三是服务入口要有访问限制,避免陌生人占用算力或读取输出目录。
Docker让AI绘画插件部署变得更可控,但它不是安全豁免工具。容器仍然可能读取你挂载进去的目录,所以挂载路径要最小化,只给运行所需目录;不要把整块系统目录挂入容器;不要用root权限随意运行未知脚本。对于普通用户,最稳妥的方案是固定镜像版本、固定数据目录、固定端口策略,再按需升级。这样既能享受ControlNet带来的精细控制能力,也能把安装维护成本降到可接受范围。
