本文则介绍另一种更轻量的方式:使用 Docker 一键部署 Z-Image-Turbo。你只需一台运行 Ubuntu 24.04、配备 RTX 3090(24GB 显存)的机器,即可快速启动服务,并通过 Web 页面或标准 API 生成无水印的高清图片。

与 ComfyUI 工作流不同,Docker 部署方式不依赖图形界面,更适合集成到 Web 应用、小程序后端或自动化流程中。

为什么选择 Docker 部署?

  • 无需学习 ComfyUI 节点操作:Docker 容器封装了全部依赖,只需写两行命令。

  • 统一 API 接口:生成逻辑通过 /api/generate 提供,任何语言均可调用。

  • 资源隔离 & 可移植:一次构建,可在本地、云服务器、K8s 环境无缝迁移。

  • 开源模型 + 本地运行:所有计算在你自己的机器上完成,无隐私泄露风险。

注意:本文使用的是开源版 Z-Image-Turbo(ModelScope 模型 ID:Tongyi-MAI/Z-Image-Turbo)。

 

01

模型下载

入魔搭(ModelScope)社区,在模型库中找到 Tongyi-MAI/Z-Image-Turbo,点击 “模型文件” → “下载模型”后,系统会提供多种下载方式(如网页直接下载、Git LFS 等),任选一种适合你的方式完成下载即可,如下图:

链接直达: https://modelscope.cn/models/Tongyi-MAI/Z-Image-Turbo/files?version=master

下载完成后,将整个模型文件夹保存到本地任意目录即可。

建议路径不要包含中文或空格,例如:

  •  
/home/yourname/Z-Image-Turbo/

安装成功如图⬆️

02

>新建两个运行所需文件

在你的工作目录(如 /home/yourname/zimage/)中,创建以下两个文件。

1、创建 Python 服务文件zimage_server.py

这是一个基于 FastAPI 的图像生成服务,负责加载模型并提供 /api/generate 接口,可直接复制下方代码:

importosimporttorchimportbase64importloggingimportuvicornfromioimportBytesIOfromcontextlibimportasynccontextmanagerfromfastapiimportFastAPI, Form, HTTPExceptionfromfastapi.middleware.corsimportCORSMiddlewarefromdiffusersimportDiffusionPipelinefromfastapi.responsesimportFileResponse
# --- 配置 ---MODEL_PATH ="/data/models/Z-Image-Turbo"HOST ="0.0.0.0"PORT =8000DEVICE ="cuda"
# 日志配置logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(message)s')logger = logging.getLogger(__name__)
ml_models = {}
@asynccontextmanagerasyncdeflifespan(app: FastAPI): logger.info(f"正在加载模型:{MODEL_PATH}...") try: # --- 官方代码逻辑移植 1: 精度设置 --- # 只推荐 bfloat16 或 float32,避免 float16 iftorch.cuda.is_available()and torch.cuda.is_bf16_supported(): dtype = torch.bfloat16 else: dtype = torch.float32 # 移动到 GPU pipe.to(DEVICE) # --- 官方代码逻辑移植 2: 内存优化 --- # 如果显存不够,取消下面这行的注释 # pipe.enable_model_cpu_offload() ml_models["pipe"] = pipe logger.info(f">>> 模型加载成功 (Precision:{dtype})") exceptExceptionase: logger.error(f"模型加载失败:{e}") raisee yield ml_models.clear() iftorch.cuda.is_available(): torch.cuda.empty_cache()
app = FastAPI(lifespan=lifespan)
app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
@app.get("/")asyncdefindex(): returnFileResponse("/workspace/index.html")
@app.post("/api/generate")asyncdefgenerate(prompt:str= Form(...)): if"pipe"notinml_models: raiseHTTPException(status_code=503, detail="Model not loaded") logger.info(f"收到任务:{prompt[:50]}...") try: pipe = ml_models["pipe"] # --- 官方代码逻辑移植 3: 关键推理参数 --- image = pipe( prompt=prompt, height=1024, # 官方默认分辨率 width=1024, num_inference_steps=9, # 官方设置: Turbo 模型只需要很少的步数 guidance_scale=0.0, # 【核心修复】Turbo 模型必须设为 0,否则会黑图或乱码 output_type="pil" ).images[0]
buffer = BytesIO() image.save(buffer,format="PNG") base64_img = base64.b64encode(buffer.getvalue()).decode()
return{"image": base64_img} exceptExceptionase: logger.error(f"生成出错:{e}") raiseHTTPException(status_code=500, detail=str(e))
if__name__ =="__main__": uvicorn.run(app, host=HOST, port=PORT)

注: 可以根据自己的实际情况修改端口,分辨率等。

2、创建前端页面文件 index.html

这是一个简单的 Web 界面,用于输入提示词并展示/下载生成的图片。

⚠️注意请将代码中的http://IP:8000替换为你服务器的实际 IP 地址(例如192.168.1.100),否则无法调用本地 API。

完整代码如下:

<!DOCTYPEhtml><htmllang="zh-CN"><head> <metacharset="utf-8"/> <metaname="viewport"content="width=device-width, initial-scale=1.0"/> <title>Z-Image-Turbo WebUI</title> <style>  :root{   --primary-color:#4a90e2;   --primary-hover:#357abd;   --bg-color:#f5f7fa;   --card-bg:#ffffff;   --text-color:#333333;   --border-radius:12px;   --shadow:04px20pxrgba(0,0,0,0.08);   }  body{   font-family: -apple-system, BlinkMacSystemFont,"Segoe UI", Roboto,    "Helvetica Neue", Arial, sans-serif;   background-color:var(--bg-color);   color:var(--text-color);   margin:0;   min-height:100vh;   display: flex;   justify-content: center;   align-items: center;   padding:20px;   }  .container{   background-color:var(--card-bg);   padding:40px;   border-radius:var(--border-radius);   box-shadow:var(--shadow);   width:100%;   max-width:550px;   text-align: center;   transition: transform0.3sease;   }  h2{   margin-top:0;   margin-bottom:30px;   color:#2c3e50;   font-weight:700;   letter-spacing: -0.5px;   }  .input-group{   margin-bottom:25px;   text-align: left;   }  label{   display: block;   margin-bottom:8px;   font-weight:600;   color:#4a5568;   font-size:14px;   }  textarea{   width:100%;   padding:14px16px;   font-size:16px;   border:2pxsolid#e2e8f0;   border-radius:8px;   box-sizing: border-box;   transition: all0.3sease;   outline: none;   background-color:#f8fafc;   font-family: inherit;   resize: none;   min-height:52px;   overflow-y: hidden;   line-height:1.5;   }  textarea:focus{   border-color:var(--primary-color);   background-color:#fff;   box-shadow:0003pxrgba(74,144,226,0.1);   }  button{   background-color:var(--primary-color);   color: white;   border: none;   padding:14px30px;   font-size:16px;   font-weight:600;   border-radius:8px;   cursor: pointer;   transition: all0.2sease;   width:100%;   box-shadow:04px6pxrgba(74,144,226,0.2);   }  button:hover{   background-color:var(--primary-hover);    transform:translateY(-1px);   box-shadow:06px8pxrgba(74,144,226,0.3);   }  button:active{    transform:translateY(0);   box-shadow:02px4pxrgba(74,144,226,0.2);   }  button:disabled{   background-color:#cbd5e0;   cursor: not-allowed;    transform: none; -webkit-transform: none; -moz-transform: none; -o-transform: none;   box-shadow: none;   }  .download-btn{   background-color:#48bb78;   margin-top:15px;   display: none;/* Hidden by default */   box-shadow:04px6pxrgba(72,187,120,0.2);   }  .download-btn:hover{   background-color:#38a169;   box-shadow:06px8pxrgba(72,187,120,0.3);   }  .download-btn:active{   box-shadow:02px4pxrgba(72,187,120,0.2);   }  #result{   margin-top:30px;   min-height:60px;   display: flex;   justify-content: center;   align-items: center;   flex-direction: column;   }  img{   max-width:100%;   border-radius:8px;   box-shadow:04px12pxrgba(0,0,0,0.1);   animation: fadeIn0.6scubic-bezier(0.22,1,0.36,1);   }  @keyframesfadeIn {   from{    opacity:0;     transform:translateY(10px)scale(0.98);    }   to{    opacity:1;     transform:translateY(0)scale(1);    }   }  .loading{   display: inline-block;   width:30px;   height:30px;   border:3pxsolid#f3f3f3;   border-top:3pxsolidvar(--primary-color);   border-radius:50%;   animation: spin1slinear infinite;   }  @keyframesspin {   0%{     transform:rotate(0deg);    }   100%{     transform:rotate(360deg);    }   }  .error-message{   color:#e53e3e;   background:#fff5f5;   padding:12px16px;   border-radius:8px;   font-size:14px;   border:1pxsolid#fed7d7;   width:100%;   box-sizing: border-box;   }  .status-text{   color:#718096;   font-size:14px;   margin-top:10px;   } </style></head><body> <divclass="container">  <h2>Z-Image-Turbo WebUI</h2>  <divclass="input-group">   <labelfor="prompt">Prompt 提示词</label>   <textarea    id="prompt"    placeholder="输入提示词,例如:a cat in the snow"    rows="1"    ></textarea>  </div>  <buttonid="generateBtn"onclick="generate()">生成图片</button>  <buttonid="downloadBtn"class="download-btn"onclick="downloadImage()">    下载图片  </button>  <divid="result"></div> </div> <script>  // Auto-resize textarea  constpromptInput =document.getElementById("prompt");   promptInput.addEventListener("input",function() {   this.style.height="auto";   this.style.height=this.scrollHeight+"px";   });  asyncfunctiongenerate(){   constresultDiv =document.getElementById("result");   constbtn =document.getElementById("generateBtn");   constdownloadBtn =document.getElementById("downloadBtn");   constprompt = promptInput.value.trim();   if(!prompt) {    // Shake animation for empty input     promptInput.style.borderColor="#e53e3e";     promptInput.focus();    setTimeout(() =>{      promptInput.style.borderColor="";     },2000);    return;    }   // UI Loading State    btn.disabled=true;    downloadBtn.style.display="none";// Hide download button during generation    btn.innerHTML=    '<span class="loading" style="width: 16px; height: 16px; border-width: 2px; vertical-align: middle; margin-right: 8px;"></span> 生成中...';    resultDiv.innerHTML="";// Clear previous result   constformData =newFormData();    formData.append("prompt", prompt);   try{    letresp =awaitfetch("http://IP:8000/api/generate", {     method:"POST",     body: formData,     });    if(!resp.ok) {      thrownewError(`HTTP error! status:${resp.status}`);     }    letdata =awaitresp.json();    if(data.image) {      resultDiv.innerHTML=`<img src="data:image/png;base64,${data.image}" alt="Generated Image" />`;      downloadBtn.style.display="block";// Show download button     }else{      thrownewError("No image data received");     }    }catch(error) {    console.error(error);     resultDiv.innerHTML=`<div class="error-message">生成失败:${error.message}</div>`;    }finally{     btn.disabled=false;     btn.textContent="生成图片";    }   }  functiondownloadImage(){   constimg =document.querySelector("#result img");   if(img) {    consta =document.createElement("a");     a.href= img.src;     a.download=`z-image-${Date.now()}.png`;    document.body.appendChild(a);     a.click();    document.body.removeChild(a);    }   }  // Allow Enter key to submit (Shift+Enter for new line)   promptInput.addEventListener("keydown",function(event) {   if(event.key==="Enter"&& !event.shiftKey) {     event.preventDefault();    generate();    }   }); </script></body></html>

03

拉取镜像并运行

我们已为你预构建好包含全部依赖的 Docker 镜像,只需两条命令即可启动服务。

1、拉取预构建镜像

在终端执行以下命令,从阿里云容器镜像仓库拉取镜像:

docker pull registry.cn-hangzhou.aliyuncs.com/rihebty/zimage-server:v1

✅ 镜像已包含 PyTorch 2.3 + CUDA 13 + FastAPI + Diffusers 等完整运行环境,无需额外安装。

2、运行容器

执行以下命令启动容器(如果端口路径不同,记得要修改一下哦):

docker run --gpus all -d \ -p8000:8000\ -v /home/z-image/Z-Image-Turbo:/data/models/Z-Image-Turbo\ -v /home/z-image/index.html:/workspace/index.html:ro \ -v /home/z-image/zimage_server.py:/workspace/zimage_server.py:ro \ --name zimage-container \ registry.cn-hangzhou.aliyuncs.com/rihebty/zimage-server:v1

参数说明

News Today

--gpus all:启用 GPU 支持

-p 8000:8000:将容器 8000 端口映射到主机 8000 端口

-v ...:挂载模型目录和两个代码文件(只读权限 :ro,更安全)

--name zimage-container:为容器指定名称,便于后续管理

⚠️ 请将 /home/yourname/... 替换为你实际的本地路径。路径错误会导致模型加载失败或页面无法访问。

3、查看是否运行成功

执行以下命令查看容器日志,确认服务是否正常启动:

docker logs -f zimage-container

运行成功会显示如下图:

04

访问 web 页面进行生图

服务启动成功后,即可通过浏览器访问本地 Web 界面进行图像生成。在浏览器地址栏中输入http://服务器IP:8000,其中“服务器IP”需替换为你实际的 IP 地址。

进入页面后,你会看到一个简洁的输入框和两个按钮。在提示词区域输入你想要生成的内容,支持中英文混合,且越具体的描述通常能带来更高质量的输出。以下是一段实际测试中使用的提示词,供你参考:

一张融合“写实质感 + 二次元画风 + 高级 CG 渲染”的《鬼灭之刃》主题海报。主体是一位站在画面中央的灶门炭治郎(可替换为任意角色),保持原有动漫面部特征与配色,但皮肤、眼睛、发丝与纹理采用写实级 CG 材质表现。角色手持日轮刀,刀刃释放淡蓝色“水之呼吸” CG 能量特效,能量呈流体状发光纹路,带有轻微粒子散射效果。他脚下是一块从雾气弥漫的浅水水面中浮出的深色湿润板岩,倒影清晰、略带二次元柔光边缘。光照与氛围(写实光影 + 动漫色调):金黄清晨体积光穿透森林树叶倾泻而下,形成真实物理感十足的体积雾与丁达尔效应,同时保留二次元式干净、高对比的光影边缘。斑驳的光斑落在炭治郎的脸部、刀刃与衣褶上,使写实材质与动漫色块互相融合。刀刃能量在水面上形成微光焦散 Caustics,与周围冷色雾气形成强烈视觉对比,制造史诗感。细节与材质(写实纹理  二次元线条):写实但带柔化处理的角色皮肤、精致的眼部渲染、半写实发丝质感。额头伤痕、耳饰与日轮刀纹路清晰,既保留原动画设计,又加入微微的金属反射与磨损细节。服装布料带有真实褶皱纹理,但边缘保留柔和的二次元描线。板岩湿润且带有微苔纹理,水面拥有真实反射与轻微折射,同时保持略微卡通化的干净色彩。背景灰烬微粒与落花片呈 CG 粒子效果,略带景深虚化。技术规格(CG 渲染 + 动漫视觉):采用虚幻引擎 5 超写实 CG 渲染风格混合高饱和、干净色块的二次元调色。8K 画质,面部与刀刃 Logo 区域超高清对焦。电影级光线追踪、漫反射 + 高光双层材质处理。动漫式色彩分级(高对比、清晰色层)与写实 CG 高动态范围光照融合。整体呈现电影海报级质感、CG 角色精度和动漫角色辨识度

实际生成效果⬆️

05

(可选)自行构建 Docker 镜像

如果你希望对运行环境进行自定义(例如升级依赖、修改服务逻辑或用于离线部署),也可以选择从零构建 Docker 镜像。整个过程只需一个 Dockerfile 和两条命令,无需额外配置。

1、准备文件目录

在你的工作目录(如 /home/yourname/zimage/)中新建一个名为 Dockerfile 的文件,并将前面创建的两个文件zimage_server.py、index.html与 Dockerfile 放在同一个目录中。

Dockerfile 文件内容可直接复制下方代码:

# 1. 基础镜像:改用 CUDA 12.4 (目前 PyTorch 支持最好的高版本)# 即使物理机驱动是 CUDA 13,容器内用 CUDA 12.4 也是完全兼容的FROMnvidia/cuda:13.0.1-runtime-ubuntu22.04
# 2. 环境变量设置ENVDEBIAN_FRONTEND=noninteractive\ LANG=C.UTF-8\ LC_ALL=C.UTF-8\ PYTHONUNBUFFERED=1\ # 显存优化参数 PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True\ # 设置默认模型路径,方便 Python 代码读取 MODEL_PATH=/data/models/Z-Image-Turbo
# 3. 安装系统依赖# 增加了 git (pip 安装 git+... 需要) 和 curlRUNapt-get update && apt-get install -y --no-install-recommends\ python3 python3-pip python3-venv\ git build-essential wget curl ca-certificates\ libgl1 libglib2.0-0libsm6 libxrender1 libxext6\ && rm -rf /var/lib/apt/lists/*
# 4. 升级 pipRUNpython3 -m pip install --upgrade pip
WORKDIR/workspace
# 5. 安装 PyTorch (CUDA 13 版本)# 这里使用了 cu130 的源,确保下载到支持 GPU 的版本RUNpip install --no-cache-dir torch torchvision --index-url https://download.pytorch.org/whl/cu130
# 6. 安装 Diffusers 和相关 AI 依赖# 补充了 sentencepiece 和 protobuf (Transformers 必须)RUNpip install --no-cache-dir git+https://wget.la/https://github.com/huggingface/diffusers.gitRUNpip install --no-cache-dir transformers accelerate safetensors modelscope sentencepiece protobuf
# 7. 安装 Web 服务依赖RUNpip install --no-cache-dir fastapi"uvicorn[standard]"pillow aiofiles python-multipart
# 8. 复制代码文件COPYzimage_server.py /workspace/zimage_server.py# 如果你有 index.html 也复制进去,没有则注释掉COPYindex.html /workspace/index.html
# 9. 暴露端口EXPOSE8000
# 10. 启动命令# 确保 host 是 0.0.0.0 才能被外部访问CMD["uvicorn", "zimage_server:app", "--host", "0.0.0.0", "--port", "8000"]

2、执行构建命令

在该目录下打开终端,运行以下命令开始构建:

dockerbuild -t zimage-server:v1 .

构建成功后,即可用以下命令运行容器(无需挂载 Python 和 HTML 文件,因为它们已打包进镜像):

docker run --gpus all -d \ -p8000:8000\ -v /home/yourname/Z-Image-Turbo:/data/models/Z-Image-Turbo\ --name zimage-container \ zimage-server:v1

至此,Z-Image-Turbo 的 Docker 部署就全部完成了。

你已经拥有了一个完全运行在本地、无水印、支持 API 调用的高清图像生成服务,既可日常使用,也能轻松集成进自己的项目,如果你有更多玩法或问题,欢迎留言交流。