最近也没有偷懒,一直没有整理笔记,主要是没找到更惊艳的工具或话题,生产互联网垃圾伤人伤己。( Claude Code 4.7 opus还在继续蹬 ,这篇内容是关于 NAS 打印相关的工具)
前提准备
外地 PC/手机、家庭 PVE 虚拟机已通过 WireGuard 组内网,可以正常互相访问;HP 打印机已正常联网。原来给孩子打作业都是通过 PVE 远程控制开机 Windows 虚拟机,把文件发过去再打印。 只有适合自己的方案才是最好的!!!
-
家里 NAS,PVE+Ubuntu(docker 服务)+Windows(平时不开机,打印或者调试家里网络用)+NAS 服务
-
打印机 HP LaserJet Pro MFP m26nw
那个让我有操作的瞬间
双职工家庭,工作日白天家里只有奶奶帮忙带娃。
每周总有那么 2-4 次,剧本几乎一模一样:低年级的孩子,老师会把每天的作业发到群里,一般口算题、写字之类的是需要打印的。
然后开始我的"远程打印仪式":
- 电脑连家里 WireGuard
- 进 PVE 上那台 为打印开着 的 Windows 虚拟机
- Windows 上登微信,下载这张图片(顺便忍受微信桌面版同步那几秒的转圈)
- 打开文件,Ctrl+P
- 孩子已经习惯了,看到老师作业内容,如果有需要打印,自己去打印机上面取 一顿操作,整套流程要 2-3 分钟,偶尔打印失败的时候,大概率是没纸了,我给老人或孩子打电话(他们都会加纸)。
这事让我难受的不是哪一步特别难,而是—— 它实在太有操作了 。
打印机自己带 WiFi,已经联网了;NAS(其实是 PVE 上的一台 Ubuntu 虚拟机)也 7×24 开着;我电脑网络畅通。但就因为缺一个"网页版打印入口",我不得不绕道一台 Windows 虚拟机,把一件物理上 3 秒就能完成的事拉长到几分钟。
直到我遇到了cups-web这个项目。
cups-web 解决了什么
一句话: 它把"打印"这件事变成了一个 HTTP 接口 。
往细了说,它做了三件事:
-
用 CUPS 当打印内核(这是 Linux/macOS 几十年来通用的打印协议栈)
-
套了一层现代化的 Web UI,浏览器拖文件就能打印
-
后端自动把 Office、OFD、图片这些格式转成 PDF 再送进 CUPS
对我这个场景来说,最关键的是第二件事—— 有了 Web UI,远程访问就是水到渠成的 。配合 WireGuard 把家里网段打通,我在任何地方打开浏览器都能用。
它给我带来的真正改变
把架构画清楚:
|
|
cups-web 完全不暴露公网 ,所有访问统一走 WireGuard 隧道。安全模型 = 内网服务的安全模型,没有引入任何新的攻击面。
部署实战
开发者部署过程和常见问题写的比较清楚,推荐阅读:https://github.com/hanxi/cups-web
先说我的环境:
-
宿主机:PVE 8.x
-
虚拟机:Ubuntu 22.04 LTS,4 核 8G
-
VM 网络:桥接(bridge),和打印机在同一个 192.168.x.0/24 网段
-
Docker:docker-ce + compose v2
-
打印机:HP LaserJet Pro MFP M26nw,WiFi 接入,路由器后台已绑定 MAC → 固定 IP
第一步:先确认 VM 能"看到"打印机
这一步是后面所有事的前提。在 Ubuntu VM 里:
|
|

如果这三步有任何一步走不通,先别动 cups-web——回头查路由器的 VLAN/AP 隔离设置,或者 PVE 桥接网络的配置。 网络通了再继续 ,否则后面会浪费很多时间在错的地方排查。
第二步:写 docker-compose.yml
官方docker-compose.yml是为 USB 直通场景设计的,对网络打印机来说有两处冗余:devices: /dev/bus/usb不需要。 根据自己设备来操作。
我的最终版本,cups 服务采用 bridge 网络模式 ——这是最干净的方式,不污染 host 网络:
|
|
几个关键点解释一下:
为什么 cups 用 bridge 而不是 host? 网上很多教程会让你用network_mode: host,理由是"让 CUPS 看到打印机的 mDNS 广播"。但对于网络打印机, 我们根本不依赖 mDNS 发现 ——后面添加打印机时直接填 IP 就行。bridge 模式让容器隔离更清晰,端口冲突风险更小。
容器间通信怎么走? CUPS_HOST=cups:631这一行——web 容器通过 Docker 内置的 DNS,用服务名cups直接访问 cups 容器的 631 端口。完全不需要走 host 网络。
第三步:起容器
在 docker-compose.yml 同级目录建一个.env:( 我首次登录也是用的开发者文档的默认密码,还是跟着作者来吧 )
|
|
然后启动:
|
|
看到 cups 容器日志里Listening for connections on 0.0.0.0:631之类的提示就 OK 了。
第四步:在 631 端口把打印机加进 CUPS(这一步是关键差异)
浏览器打开http://<VM IP>:631,左上角 Administration → Add Printer ,用 .env 里的账号密码登录。
USB 教程到这里会让你在列表里选"USB Printer #1"之类的本地设备。 我们不一样 :
- Other Network Printers 区域,选 Internet Printing Protocol (ipp)
- Continue ,在 Connection 输入框里填:
把
192.168.x.x换成 M26nw 的实际 IP。
|
|
- Name / Description / Location 随便起,比如
HP_M26nw、家里打印机、客厅 - 重点:勾选 “Share This Printer” ——cups-web 通过 IPP 反向连接 CUPS 时,只能看到 shared 的打印机。这个勾不打,后面 cups-web 里就是空列表。
- Make 选 HP ,Model 选 IPP Everywhere (M26nw 支持 IPP Everywhere,几乎 driverless,比厂商专属驱动省心)
- Add Printer 加完之后在 Printers 标签页能看到它,状态是 Idle。打一份测试页(Maintenance → Print Test Page),打印机吐出一张 CUPS 自带的测试图就说明本地链路打通了。

第五步:访问 cups-web 实测
浏览器打开http://<VM IP>:1180,默认账号密码都是admin。
登录后第一时间做两件事:
- 改密码(右上角用户菜单)
- 在打印机列表里应该能看到刚才那台
HP_M26nw。如果没看到,回 631 检查 Share This Printer 有没有勾上 试着拖一张 PDF 进去,选份数,点 Print。打印机吐纸——本地链路就完成了。
部署实战 Part 2:让它"出门"
到这一步,cups-web 已经能在家里局域网内用了。但我的核心需求是 远程 ,所以需要 WireGuard 把家里网段打通到外面。
WireGuard 的服务端/客户端配置我之前写过一篇详细的:
上面这篇覆盖了配置文件、密钥生成、端口转发、DDNS 这些。这里就不重复了,只讲与打印场景特别相关的两个细节。
一段时间下来的副产品
用了几周之后,发现一些当初没预料到的好处。
PVE 上的 Windows 虚拟机直接基本退役了, 它原来存在的最大意义就是"打印代理"。
等待的焦虑没了 ,这是最实在的改善。
cups-web 自带打印记录有意外用处。 每条记录有时间、文件名、份数等,比如有时候上午语文老师发了,下午其他老师也需要打印,通过打印记录可以随时发现上午的材料有没有打印过。当然,这事见仁见智,介意隐私的可以把记录保留时间调短。
性能完全不是问题。 一张图片上传到打印开始吐纸大概 2-3 秒,Office 文档 LibreOffice 转 PDF 大概 5-8 秒。4 核 8G 的 VM 跑这个绰绰有余。
几个真踩过的坑
不是所有教程上的坑我都遇到了。下面这几个常见的挑出来说。
坑 1:M26nw 在 cups-web 里能选"双面打印",但它其实是单面机
M26nw 物理上不支持自动双面(要双面得手动翻面再送进去)。但 cups-web 的 UI 上"双面"选项是亮的,可以勾。
第一次手贱勾了,打印机吐出来的是单面,第二张纸又打了同一面内容,浪费了半张纸。
原因是 IPP Everywhere driverless 模式下,打印机能力上报有时候不准。cups-web 显示的是"理论上 CUPS 支持的所有选项",而不是"打印机真实支持的能力"。
解决方式 :习惯就好,永远默认单面。如果想彻底干掉这个误操作的可能,可以在 631 端口里给这台打印机改 PPD,把双面选项去掉——但我懒得搞,记住"单面机就是单面机"这一条就行了。
坑 2:路由器重启后打印机 IP 变了 → 一次性解决
这个其实算不上"坑",是部署之前就该做好的事: 第一次部署前,先在路由器后台给打印机的 MAC 地址绑定一个固定 IP 。
我用的小米路由器,路径是"设置 → 局域网 → DHCP 静态分配"。把 M26nw 的 MAC 填进去,分一个明确的 IP,从此再也没变过。
如果不做这一步,路由器重启或者打印机离线一段时间重连,DHCP 分配的 IP 可能变化,CUPS 里那条ipp://192.168.x.x/ipp/print就指向了空气。
cups-web 那台 VM 同理,一起绑了。
这些场景不推荐这套方案
写这种文章的人很多会避开"什么时候不该用",因为劝退看起来像在唱衰自己的方案。但我觉得 讲清楚边界才对得起读者 。
家里没人能配合"加纸 + 取件" 的,这套也用不起来。再优雅的远程打印,本质还是要有人物理上去做这两件事。
只用苹果设备,且只打 PDF/图片 的,AirPrint 已经够了,没必要折腾这一套。cups-web 的核心价值是"格式转换"和"远程统一入口",这两条对你不适用就划不来。
写在最后
cups-web 是hanxi维护的开源项目,MIT 协议。仓库地址:github.com/hanxi/cups-web。
作者在 GitHub Issues 里非常活跃,README 里能看到一连串 issue 编号——大量驱动支持都是根据用户反馈陆续加上去的。作者也维护了微信群(Issue #36),开发节奏稳定,0.x 版本但功能已经相当完整。
📎 参考文章
-
WireGuard 配置:https://11010.net/p/nas-intranet/
-
CUPS 官方:cups.org
-
IPP Everywhere:ietf.org/rfc/rfc8011