N1 盒子做打印服务器:Docker CUPS + HP CP1025 完整记录
背景
最近从本地淘了一台 HP LaserJet CP1025 彩色激光打印机,USB 接口的,每次打印都必须要开电脑。之前了解到如果要实现无线打印需要一个小白学习盒子,后来从网上搜有办法可以实现无线打印;
手头正好有一台 N1 盒子,刷了 OpenWrt 当旁路由用。
想法很简单:N1 盒子一直开着,USB 口闲着,打印机挂上去,Docker 跑个 CUPS 服务,整个局域网都能打印,手机也能通过 AirPrint 直接打。
看起来是个十来分钟能搞定的活。实际上折腾了大半天。这里所有命令和日志都是AI帮我实现的,全程没有敲一个代码,因为我不是程序员哈哈哈
一个办法就是通过 openwrt 内的 usb 网络打印,电脑可以无线,但是ios、安卓无法实现无线打印
另一个办法是安装CUPS实现原生AirPrint
踩坑记录
搜了一圈,找到 chuckcharlie/cups-avahi-airprint 这个 Docker 镜像,自带 AirPrint 和 Avahi 服务发现。
拉镜像、创建容器、打开 CUPS 后台(http://N1的IP:631)、添加打印机——USB 口确实检测到了 CP1025,驱动列表里也有 HP LaserJet CP 1025, hpcups 3.26.4,选它,点打印测试页。
卡住了。状态显示 "Filter failed"。
查日志,关键报错:
hplip.plugin-error
m_Job initialization failed with error = 48
PID xxx (/usr/lib/cups/filter/hpcups) crashed on signal 11.
hpcups 驱动需要 HP 的专有二进制插件,没装这个就直接崩。
然后开始了一段漫长且痛苦的尝试:
hp-plugin命令——容器里根本没这个命令从 SourceForge 下载
hplip-3.26.4-plugin.run——这个版本压根没发布独立插件文件从 HPLIP 完整包里找
plugin.py手动运行——脚本用了 Python 2 的URLopener,新版 Python 不兼容手动拷贝
.so文件到/usr/share/hplip/prnt/plugins/——hplip 有验证机制,光拷文件不行
全堵死了。
后来在树莓派论坛看到有人说 HP CP1025 用 foo2zjs 开源驱动能正常打印,不需要 HP 任何专有插件。试了一下,果然成了。
这里感谢这篇文章的教程,同样适合部署在 nas 里:https://4ft35t.github.io/post/hp-cp1025-set-airprint-on-dsm7-via-docker-cups/
下面是重新来的完整步骤。
第一步:创建 CUPS 容器
docker run -d
--name=airprint
--restart=always
--net=host
--privileged=true
-e TZ="Asia/Shanghai"
-e CUPSADMIN="admin"
-e CUPSPASSWORD="pass"
-e HOST_OS="OpenWrt"
-e TCP_PORT_631="631"
-v /var/run/dbus:/var/run/dbus
-v /var/lib/docker/data/cups/config:/config
-v /var/lib/docker/data/cups/services:/services
-v /dev/bus/usb:/dev/bus/usb
chuckcharlie/cups-avahi-airprint:latest
参数说明:
--net=host— 用宿主机网络,AirPrint 的 mDNS 广播靠这个--privileged=true— 访问 USB 设备需要特权模式-v /var/run/dbus— Avahi 做局域网服务发现要用 D-Bus-v /dev/bus/usb— USB 打印机设备映射进容器CUPSADMIN/CUPSPASSWORD— CUPS 后台的登录账号密码
跑起来之后确认一下:
docker ps
看到 airprint 容器状态是 Up 就行。
第二步:进容器装编译工具
这个镜像是基于 Alpine Linux 的,没有 apt,用 apk。而且没有 bash,只能用 sh:
docker exec -it airprint sh
装编译需要的东西:
apk add --no-cache make gcc g++ libc-dev cups-dev git
装完确认一下:
which make && which gcc && make --version | head -1
输出 GNU Make x.x.x 就行。
第三步:下载 foo2zjs 源码
cd /tmp
wget "https://github.com/koenkooi/foo2zjs/archive/refs/heads/master.tar.gz" -O foo2zjs.tar.gz
我这边 N1 容器内直接从 GitHub 下载是成功的。如果你的环境连 GitHub 不通(N1 的 OpenSSL 有时候会跟某些 HTTPS 站点握手失败),就在电脑浏览器打开上面那个地址下载,然后传进去:
# 电脑上
scp master.tar.gz root@N1的IP:/tmp/
# N1 宿主机上
docker cp /tmp/master.tar.gz airprint:/tmp/foo2zjs.tar.gz
第四步:编译安装
tar xzf foo2zjs.tar.gz
cd foo2zjs-master
make
编译过程会输出一大堆东西,中间会有 warning 和 date: invalid date 之类的,不影响,忽略。只要最后没报 Error 停下来就行。
然后安装:
make install
又是大量输出,看到一堆 # Install ... 的信息就说明装好了。
第五步:重启 CUPS
kill -HUP $(pidof cupsd)
不用重启容器,这行就够。
第六步:添加打印机
浏览器访问 http://N1的IP:631,用你创建容器时设的账号密码登录(我设的是 admin / pass)。
点 Administration → Add Printer
系统会检测到 USB 打印机,选 HP LaserJet CP 1025
给打印机起个名字,勾上 Share This Printer(共享给局域网)
选驱动的时候,往下翻,找这个:
HP LaserJet Pro CP1025nw Foomatic/foo2zjs-z3 (en)不要选 hpcups 开头的那个。虽然型号写的是 CP1025nw,但 CP1025 和 CP1025nw 用的是同一套 foo2zjs 驱动,选它就行。
点 Add Printer 完成
在打印机页面点 Print Test Page,能打出来就搞定了。
客户端连接
Windows
设置 → 蓝牙和设备 → 打印机和扫描仪 → 添加设备。
系统会自动发现 HP LaserJet CP 1025 @ airprint,直接添加就行,Windows 会自己下载驱动。

iPhone / iPad / Mac
什么都不用配。AirPrint 是系统级支持,任何 App 里点"打印"都能看到这台打印机。

Linux
装个 cups-browsed 就能自动发现:
sudo apt install cups-browsed
第七步:构建自定义镜像(一步到位,解决重启后打印机丢失的问题)
前面六步做完,打印机能用了。但有个大坑:OpenWrt 重启后,打印机配置会丢失。
原因是容器的 /root 和 /tmp 是 tmpfs(内存文件系统),重启后文件全部消失。宿主机挂载的 /config 目录在某些情况下也会被清空。
用 Dockerfile 把 foo2zjs 驱动、打印机配置、PPD 文件、恢复脚本全部打进镜像层,彻底解决。
7.1 导出打印机配置和 PPD 文件
docker exec airprint sh -c "cat /etc/cups/printers.conf" > /tmp/printers.conf
docker exec airprint sh -c "cat /config/ppd/HP_LaserJet_CP_1025.ppd" > /tmp/HP_LaserJet_CP_1025.ppd
确认两个文件都有内容(空文件会导致后面 COPY 进镜像的也是空的):
head -3 /tmp/printers.conf
head -3 /tmp/HP_LaserJet_CP_1025.ppd
7.2 写 Dockerfile
cat > /tmp/Dockerfile << 'DOCKERFILE'
FROM chuckcharlie/cups-avahi-airprint:latest
# 编译安装 foo2zjs 驱动
RUN apk add --no-cache make gcc g++ libc-dev cups-dev &&
cd /tmp &&
wget "https://github.com/koenkooi/foo2zjs/archive/refs/heads/master.tar.gz" -O foo2zjs.tar.gz &&
tar xzf foo2zjs.tar.gz &&
cd foo2zjs-master &&
make && make install &&
cd / && rm -rf /tmp/foo2zjs* &&
apk del make gcc g++ libc-dev cups-dev
# 打印机配置和 PPD 文件写入镜像层
COPY printers.conf /etc/cups/printers.conf.default
COPY HP_LaserJet_CP_1025.ppd /etc/cups/ppd.default/HP_LaserJet_CP_1025.ppd
# 恢复脚本:开机时如果宿主机配置或 PPD 为空,从镜像备份恢复
RUN echo '#!/bin/sh' > /etc/cups/init-printers.sh &&
echo 'if [ ! -s /config/printers.conf ] && [ -f /etc/cups/printers.conf.default ]; then' >> /etc/cups/init-printers.sh &&
echo ' cp /etc/cups/printers.conf.default /config/printers.conf' >> /etc/cups/init-printers.sh &&
echo 'fi' >> /etc/cups/init-printers.sh &&
echo 'if [ ! -f /config/ppd/HP_LaserJet_CP_1025.ppd ] && [ -f /etc/cups/ppd.default/HP_LaserJet_CP_1025.ppd ]; then' >> /etc/cups/init-printers.sh &&
echo ' mkdir -p /config/ppd' >> /etc/cups/init-printers.sh &&
echo ' cp /etc/cups/ppd.default/HP_LaserJet_CP_1025.ppd /config/ppd/HP_LaserJet_CP_1025.ppd' >> /etc/cups/init-printers.sh &&
echo 'fi' >> /etc/cups/init-printers.sh &&
chmod +x /etc/cups/init-printers.sh
# 在启动脚本 set -x 后面插入恢复脚本
RUN sed -i '/^set -x$/a /etc/cups/init-printers.sh' /root/run_cups.sh
DOCKERFILE
7.3 构建镜像
需要几分钟(下载 foo2zjs 源码并编译):
docker build -t cups-foo2zjs /tmp/
构建完后把构建文件存到持久目录(/tmp 是 tmpfs,OpenWrt 重启后文件就没了):
mkdir -p /var/lib/docker/data/cups/dockerbuild
cp /tmp/Dockerfile /tmp/printers.conf /tmp/HP_LaserJet_CP_1025.ppd /var/lib/docker/data/cups/dockerbuild/
以后重建镜像就用:
docker build -t cups-foo2zjs /var/lib/docker/data/cups/dockerbuild/
7.4 重建容器并验证
docker stop airprint && docker rm airprint
docker run -d
--name=airprint
--restart=always
--net=host
--privileged=true
-e TZ="Asia/Shanghai"
-e CUPSADMIN="admin"
-e CUPSPASSWORD="pass"
-e HOST_OS="OpenWrt"
-e TCP_PORT_631="631"
-v /var/run/dbus:/var/run/dbus
-v /var/lib/docker/data/cups/config:/config
-v /var/lib/docker/data/cups/services:/services
-v /dev/bus/usb:/dev/bus/usb
cups-foo2zjs
验证 PPD 和配置:
docker exec airprint sh -c "ls /config/ppd/ && cat /etc/cups/printers.conf | grep -c Printer"
输出 PPD 文件名和 1 说明成功。试打测试页确认能打印,然后重启 OpenWrt 做最终验证。
备忘
踩过的坑,记一下:
hpcups 驱动(hplip)需要 HP 专有插件,Alpine 容器里基本装不上。别折腾了,直接用 foo2zjs
Alpine 的 apk 源有时候会抽风(403、Permission denied),默认源能用就用默认源,别换国内镜像
N1 的 OpenSSL 连部分 HTTPS 站点会握手失败(ghp.ci、SourceForge 都试过不行),GitHub 主站倒是能连
plugin.py依赖 Python 2 的URLopener,新版 Python 不兼容,改 Python 代码更麻烦,不如直接编译 foo2zjs选驱动的时候看清楚:要选带 foo2zjs 字样的,不要选 hpcups
/root和/tmp是 tmpfs(内存文件系统),重启后文件丢失,docker commit也无法保存这些目录的内容docker cp在这个容器里有权限问题,用docker exec sh -c "cp ..."绕过Dockerfile 构建时,
COPY的文件必须确认有内容,否则 COPY 进去的是空文件PPD 文件(
/config/ppd/)也会在重建容器时丢失,必须一并打进镜像构建文件(Dockerfile + printers.conf + PPD)要存到持久目录
/var/lib/docker/data/cups/dockerbuild/
作者提示含AI生成内容。作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

赞赞赞赞赞
校验提示文案
真实小白
校验提示文案
值友3478925946
校验提示文案
Master0123
校验提示文案
林雨梦
校验提示文案
小糖017
校验提示文案
值友2565893140
校验提示文案
值友6100999733
校验提示文案
值友6100999733
校验提示文案
值友2565893140
校验提示文案
小糖017
校验提示文案
Master0123
校验提示文案
值友3478925946
校验提示文案
真实小白
校验提示文案
林雨梦
校验提示文案
赞赞赞赞赞
校验提示文案