
搞了个绿联 NAS除了存电影和备份照片总得让它干点更有意思的活。我挑了一个特别实用的项目来练手在绿联 UGREEN NAS 上用 Docker 部署一个本地抠图工具镜像名是 withoutbg。一句话说清楚它是干嘛的把图片拖进去去掉背景输出一张透明底 PNG整个过程完全在 NAS 本地跑不用上传到任何云端服务。这东西特别适合这几类人经常做电商图、商品图怕把原图传到第三方平台泄露素材的需要批量处理透明底素材的设计师或运营以及手上有 NAS想练练 Docker 部署、又不想折腾太复杂项目的入门玩家。整篇我按照从思路到实操、再到常见坑的顺序来写你照着走一遍基本半小时内能把服务跑起来。1. 项目整体定位与部署思路拆解1.1 为什么要在 NAS 上跑一个抠图工具先解决一个问题抠图工具那么多网页版、手机 App、Photoshop 插件为什么非要放在 NAS 上我自己的使用场景是这样的平时做一些产品演示图需要给设备照片换背景色素材都在 NAS 里把图抠完又得存回 NAS。以前流程是下载到本地、拖进网页工具、等上传、等处理、再下载、再传回 NAS一来一回少说十分钟遇到网络慢的时候更崩溃。而且网页工具处理的是 你的图片上传到别人服务器总有点不踏实。在 NAS 上部署一个本地抠图服务等于把处理能力搬到了素材旁边。文件在内网里直接流转不上外网速度快安全性也可控。withoutbg 这个项目正好符合需求体积不大、模型本地推理、有 Web UI、提供 API 接口用 Docker 一条命令就能装进绿联 NAS 的容器系统里。装上之后浏览器打开 NAS 的 IP 加端口拖图进去就能用。1.2 绿联 NAS 跑 Docker 的现状绿联 NAS 的 Docker 功能在 dxp4800 plus 这一代机型上做得还算顺手。它基于标准的 Docker 引擎支持 docker-compose也能直接命令行操作。不过要注意的是绿联的 Docker 管理界面做过二次封装图形界面里有些参数设置跟原生 Docker 不完全一样尤其是端口映射和存储卷挂载这两块坑比较多。我后面会在实操部分专门讲清楚哪些必须在图形界面里点、哪些建议直接用 SSH 命令行操作。如果你手头是绿联的私有云 UGOS Pro 系统一般自带应用中心里面能装 Docker 管理面板但默认可能没开 SSH。不开 SSH 的话也能部署但排查问题会很痛苦所以我建议先去系统设置里把 SSH 打开后面步骤会顺畅很多。1.3 选型背后的考虑当时在 withoutbg 和另一个比较流行的 rembg 之间犹豫了一阵。rembg 是老牌项目模型选择多、社区活跃但它的默认模型对复杂背景支持一般而且镜像体积偏大。withoutbg 的特点是开箱即用它内部也是基于深度学习的语义分割模型但对边缘处理做了优化像头发丝、透明物体边缘这些容易翻车的场景效果更稳。我实测了几张产品图确实比 rembg 默认模型干净边缘没有那种白边残留。再来就是部署复杂度。withoutbg 提供的 Docker 镜像直接包含了模型和运行环境不用自己下载模型文件这对 NAS 用户非常友好。模型文件通常几百兆甚至上 GB如果镜像里不带你就得在容器里手动下载国内网络环境下载这些模型经常卡死。withoutbg 把这一层免掉了。2. 部署前的准备工作与关键参数说明2.1 硬件和系统环境要求绿联 dxp4800 plus 这类 x86 架构的 NAS 跑起来没问题只要是 x86 平台、Docker 版本在 20 以上基本都行。ARM 机型比如一些入门款也能跑但推理速度会慢一些这个后面会有数据对比。内存方面建议至少 4GB因为抠图模型推理时大概要占用 1GB 到 1.5GB 内存加上系统和其他容器4GB 是底线。我机器上挂了 Jellyfin、Transmission、Home Assistant 这些常驻容器平时内存占用在 50% 左右跑 withoutbg 没有压力。硬盘空间的话镜像解压后大约 2GB 左右包含模型文件预留 5GB 比较稳妥。如果你后续要玩其他 AI 项目还得再留点余量。2.2 端口规划withoutbg 默认监听 5000 端口我把 NAS 上的 5001 映射到容器的 5000。为什么不直接用 5000因为绿联 NAS 上很多容器喜欢抢 5000 端口比如某些下载工具、网盘工具冲突概率不小。建议先查一下 NAS 上还有哪些端口被占用了用命令netstat -tlnp | grep 5000看一眼有输出就换个映射端口。容器内部端口不用改只改宿主机这边的映射端口。后面访问地址就是http://NAS的IP:5001。2.3 目录挂载规划我在存储空间里建了一个专门放容器数据的目录路径大概是/volume1/docker/withoutbg下面分两个子目录uploads存放待处理的图片。容器把上传的图片临时放到这里处理完可以保留也可以自动清理。outputs存放抠好的透明底 PNG。这里建议放在 NAS 的机械硬盘阵列上因为最终产物要长期保存和使用。这里有一个细节很多人会忽略模型文件不要放在机械硬盘阵列上最好放在 SSD 缓存或者系统盘上。原因是模型文件每次容器启动都要加载机械硬盘加载几百 MB 的模型文件要等半天SSD 几秒钟就完成了。如果你在绿联上做了 SSD 缓存把整个 docker 目录放到缓存加速的存储池里体验会好很多。我实测过模型加载时间从机械盘的 20 秒左右降到 SSD 上的 4 秒左右差别非常大。3. 实操部署从 SSH 到容器跑通3.1 开启 SSH 并进入命令行绿联 UGOS Pro 系统默认关闭 SSH。打开方式控制面板 → 终端机管理 → SSH 服务启用并设置端口默认 22 即可。然后用你平时登录 NAS 的管理员账号通过 SSH 连上去ssh admin你的NAS地址连接后先确认 Docker 环境正常docker version如果提示找不到 docker 命令说明 PATH 没配好试试/usr/bin/docker version或者直接/volume1/appstore/ContainerManager/usr/bin/docker version。绿联不同固件版本的 Docker 安装路径不太一样这是第一个容易踩坑的地方。3.2 Docker 命令行部署 withoutbg官方给的部署命令大致是这样docker run -d \ --name withoutbg \ -p 5001:5000 \ -v /volume1/docker/withoutbg/uploads:/app/uploads \ -v /volume1/docker/withoutbg/outputs:/app/outputs \ withoutbg/withoutbg:latest逐条解释一下-d后台运行容器。--name withoutbg给容器起个名字后面docker logs、docker restart都用这个标识。-p 5001:5000宿主机 5001 映射到容器 5000。-v参数把 NAS 本地目录挂进容器实现数据持久化。withoutbg/withoutbg:latest镜像完整名称。执行完命令后用docker ps查看容器状态如果是Up就基本成了。再用docker logs withoutbg看看日志里有没有报错。正常会看到类似模型加载完成、服务监听 5000 端口的输出。3.3 使用绿联图形界面部署可选如果你不想用命令行绿联 Docker 界面里也能操作。在镜像页面拉取withoutbg/withoutbg然后在容器页面创建注意这几处端口设置本地端口填 5001容器端口填 5000。存储空间把 NAS 上的 uploads 和 outputs 目录分别挂载到容器内的对应路径。资源限制可以限制内存使用建议给 2GB防止模型推理时占用过多内存影响其他容器。图形界面有个问题保存配置后不能直接看到日志输出得去容器详情页找日志标签。遇到启动失败的情况先看日志再排查别乱改配置。3.4 验证服务是否正常浏览器访问http://你的NAS地址:5001能看到一个简洁的 Web 页面中间是拖拽上传区域这就说明服务跑起来了。随手拖一张带背景的图片进去等待几秒右侧会生成抠好的 PNG 预览提供下载按钮。如果页面打不开先确认容器状态和端口映射docker ps -a | grep withoutbg docker port withoutbg前者看容器是否退出后者看端口映射是否生效。如果容器反复重启八成是目录挂载权限问题或模型文件不一致看日志最快。4. 核心原理与 API 调用方式4.1 它到底是怎么把背景去掉的withoutbg 的底层跟大多数 AI 抠图工具类似用的是一个经过大量人像、商品、动物图片训练的语义分割模型。简单理解模型把图片中每个像素分类判断它属于前景还是背景然后按像素生成一个 Alpha 通道透明通道。最终输出就是把背景区域 Alpha 值设为 0 的 PNG。这个过程中有两个环节特别影响效果一个是边缘细化matting refinement。直接按分割结果切边缘会出现锯齿所以模型会额外预测边缘区域的透明度渐变头发丝、毛绒玩具边缘这种地方属于半透明区域细化得好不好直接决定抠图是否自然。withoutbg 在这部分调得比较激进边缘保留更完整但遇到纯白背景和主体颜色相近时反而容易出现抠多了的情况。另一个是前背景颜色杂糅。有些图片的背景是渐变色或者主体边缘有一圈环境光直接抠出来边缘会留下光晕。withoutbg 的输出会自动做一定程度的去边处理减少这种色边现象。4.2 从 Web 界面升级为 API 调用Web 界面适合单张手动处理但如果你有几十张图要处理一张张拖进去太傻了。withoutbg 提供了 HTTP API直接用命令或脚本批量调用。官方 API 端点一般是POST /remove请求格式是 multipart/form-data字段名是file。示例curl -X POST http://你的NAS地址:5001/remove \ -F file/path/to/input.jpg \ -o output.png执行后服务器返回处理好的 PNGcurl 通过-o保存到本地。这是单张图最简单的调用方式适合先验证 API 是否可用。如果想批量处理整个目录下的图片一个 for 循环搞定for img in /volume1/docker/withoutbg/uploads/*.jpg; do name$(basename $img .jpg) curl -s -X POST http://127.0.0.1:5001/remove \ -F file$img \ -o /volume1/docker/withoutbg/outputs/$name.png echo 已处理: $name done这一步是在 NAS 本机执行的不需要经过外网所以即使没有公网 IP 也能顺利跑。4.3 用 Python 脚本做更精细的批量处理如果你的需求不只是去掉背景这么简单还可以写个 Python 脚本把调用 API 和后处理结合起来。比如import requests url http://127.0.0.1:5001/remove files {file: open(input.jpg, rb)} resp requests.post(url, filesfiles) with open(output.png, wb) as f: f.write(resp.content)如果想在抠图之后再调整图片尺寸可以用 Pillow 打开输出 PNG再 resize 一下。这里有个 Pythonrequests上传的细节图片体积大的时候requests库默认会把文件读入内存多张图连续跑可能内存飙升。建议加一句files {file: (filename, open(...), image/jpeg)}带文件名和 MIME 类型更稳。内存不够的时候可以先压缩一下原图再上传。4.4 关于模型与隐私的说明所有推理都在本地容器里完成图片不会离开你的 NAS。这一点在商业场景里非常重要。比如你要处理一些尚未发布的新品照片放在本地跑既不会泄图也不需要依赖外部服务的稳定性。还有一点容器镜像更新时模型可能会跟着升级处理效果会有细微变化。用latest标签的好处是保持最新但坏处是某次升级后可能跟你的使用习惯不一样。如果需要稳定复现建议固定到具体版本号比如withoutbg/withoutbg:1.2.3。5. 常见问题与避坑经验5.1 容器启动了但页面打不开这种情况十有八九是端口映射问题。我之前遇到过一次绿联 Docker 图形界面里把端口填反了本地口填了 5000容器口填了 5001结果访问 5000 一直没反应。命令行部署则比较少出现这种问题。排查路径就是docker port withoutbg看映射是否正确。在 NAS 本机执行curl -I http://127.0.0.1:5001返回HTTP/1.1 200 OK说明服务正常。本机通但外部访问不通检查防火墙或路由器端口转发设置。5.2 处理大图时内存飙升默认情况下模型输入尺寸有上限超过会压缩但压缩大图的过程本身比较吃内存。如果传一张 8000x6000 的相机原图即使模型会压缩处理时内存占用也可能超过 2GB。处理这种超大图建议先在本地把图片缩到 2000 像素以内再上传速度更快内存也更稳。5.3 输出图片四周有残留背景这种情况常见于主体颜色和背景相近、或者主体有大面积半透明区域。解决办法是先尝试用 Web 界面里的精细处理选项如果有的话或者把图片背景换成对比度更高的颜色再抠一次。调 API 的话可以在请求里加一个参数来控制边缘敏感度具体参数名需要看对应版本的接口文档不同版本略有差异。5.4 模型加载慢或首次启动时间长首次启动时容器要初始化模型机械盘上可能要等 30 秒以上这不是故障耐心等就是。如果每次启动都要等很久参考前面说的把 docker 目录放到 SSD 缓存存储池。另外容器启动后第一次处理图片时模型要加载到内存会有几秒钟延迟属于正常现象。5.5 容器自动更新导致服务断掉我习惯给容器配置自动更新但有次绿联系统升级后自动拉取了最新镜像新镜像的 API 路径变了我的脚本全废。后来学乖了重要服务固定版本号测试版本用 latest。生产环境建议固定版本避免意外断服。6. 从单机工具到自动化工作流6.1 定时任务批量处理NAS 的优势是 7x24 小时在线。我可以把待处理的图片放到指定目录然后写一个周期性任务每 10 分钟检测一次新文件自动调用 withoutbg API 处理把结果丢到 output 目录。这样等于做了一套简单的自动化抠图流水线。用 crontab 实现*/10 * * * * /volume1/docker/withoutbg/scripts/process_new.sh脚本里维护一个已处理文件列表只处理新增的图片避免重复处理。6.2 与绿联的相册或文件服务联动更进一步可以把 output 目录映射到绿联的共享文件夹这样家人或同事在局域网内直接访问共享目录就能拿到抠好的素材不用每个人都去开 Web 界面。绿联的文件服务支持 SMB/NFSoutput 目录设置为共享后在 Windows 资源管理器里直接映射网络驱动器取图非常方便。6.3 还可以扩展的技能点部署这个项目虽然不难但整条链路涉及的知识点不少Docker 端口映射、目录挂载、容器日志排查、API 调试、任务调度。把这套逻辑吃透之后再去部署其他容器项目基本能举一反三。比如你后面想在 NAS 上跑一个本地大模型、部署一个自动化下载服务这些都是同一套思路。7. 性能实测数据参考以下是我在绿联 dxp4800 plus 上的一组实测数据供你参考项目数据镜像下载耗时国内网络约 8 分钟容器启动到服务可用约 5 秒SSD 存储池首张图处理耗时1920x1080约 2 秒批量处理 50 张 1200x800 商品图约 4 分钟处理过程中内存峰值约 1.5GB容器磁盘占用约 2.3GB这组数据说明即便不是高端配置处理常规电商图也完全够用。如果需要更快可以考虑给容器分配更多 CPU 核心绿联的设备一般处理器不算差瓶颈往往在磁盘 IO 和内存带宽上。我个人在这套部署上踩过几个坑最深的体会是先把日志看懂再动配置。Docker 部署乍一看参数多但绝大多数问题都能从日志里找到答案。你按着这篇文章的流程走一遍把 withoutbg 跑起来之后可以顺手试一张自己经常处理的图片感受一下本地抠图的速度和效果。后面不管是批处理还是跟其他服务联动都会变得很顺手。