printer-agent 部署教程

把一台 Linux 主机变成 PrintHub 社区里的「共享打印机」节点

printer-agent 是一个用 Rust 编写的小型守护进程,部署在打印机所在的局域网主机上。它通过 WebSocket 与 printhub-host 保持长连接,收到打印任务后把 PDF 拉取到本地,再通过 IPP 协议把任务投递给打印机。

1. 架构概览

整个链路分为三段:浏览器(Next.js 前端)→ printhub-host(Go 后端,统一鉴权、任务调度、文件存储)→ printer-agent(Rust 客户端)→ IPP 打印机。printer-agent 不开放任何对外端口,只作为出站客户端。

浏览器 ──HTTP──> printhub-host ──WebSocket──> printer-agent ──IPP──> 打印机
                                       │
                                       └──对象存储 (PDF 任务文件)──

2. 准备环境

在开始之前请确认以下条件:

  • 支持的发行版:Debian 11 (bullseye) / 12 (bookworm) / 13 (trixie),Ubuntu 20.04 / 22.04 LTS / 23.04+。
  • 一台已开启 IPP 服务的打印机(绝大多数支持 Wi-Fi 的家用 / 办公打印机都自带),主机与打印机在同一个局域网。
  • agent 主机能够访问 printhub-host 的 443 / 80 端口(WebSocket);同时能够访问打印机的 IPP 端口(默认 631)。
  • 一个由 PrintHub 后台签发的 printer-agent 注册 token(参见下一节)。

3. 获取注册 token

注册 token 由 PrintHub 后台为每位用户签发,一个 token 对应一台打印机。

  1. 用您的账户登录 PrintHub,依次进入「设置」→「打印机」;
  2. 在「我的打印机」页签点击「签发 token」按钮;
  3. 在弹出的对话框中确认签发,复制显示的 token(格式为 phb.<owner_uuid>.<secret>)。
  4. ⚠️ token 仅展示一次,请立即写入 agent 的配置文件。

token 写入后,agent 首次连入 WebSocket 时,printhub-host 会自动为您创建打印机并把 token 以 key_prefix + bcrypt 哈希形式存库。详细协议请参考 printhub-host 文档中的「自动注册机制」一节。

4. 安装 — DEB 包(推荐)

DEB 包由 Gitea Actions 在 tag v*.*.* 推送时自动构建,从项目的 Release 页面下载。

前往 https://git.duguying.net/cloudprinter/printer-agent/releases 下载最新 printer-agent_<version>_amd64.deb。

使用 dpkg 安装并自动修复依赖:

sudo dpkg -i printer-agent_<version>_amd64.deb
sudo apt-get install -f

安装后的文件布局

/usr/local/printer-agent/bin/printer-agent
/usr/local/printer-agent/bin/pdf2printable
/usr/local/printer-agent/conf/config.toml
/usr/bin/printer-agent  (符号链接)
/usr/bin/pdf2printable (符号链接)

5. 安装 — Docker

官方镜像基于 ubuntu:latest,工作目录为 /root/printer-agent。挂载配置目录并以后台模式运行:

准备配置目录

在宿主机上创建 /etc/printer-agent 目录,把 conf/config.toml 放进去。

启动容器

docker run -d --name printer-agent \
  --restart unless-stopped \
  -v /etc/printer-agent/conf:/root/printer-agent/conf:ro \
  -v /var/log/printer-agent:/root/printer-agent/log \
  git.duguying.net/cloudprinter/printer-agent:latest

6. 安装 — 源码编译

适合需要自定义功能或使用未发布版本的用户。

编译依赖:Rust 1.70+、g++、libpoppler-glib-dev、libglib2.0-dev、libcairo2-dev、libjpeg-dev、libcurl4-openssl-dev、zlib1g-dev。

make build           # debug 编译
make pack           # release 编译并输出到 dist/
make deb            # 重新打 DEB 包(会自动编译 ppm2pwg)

Windows 用户请改用 PowerShell 脚本:powershell -ExecutionPolicy Bypass -File .\build.ps1 release

7. 安装 — Windows

如需在 Windows 上使用图形化安装包,请前往「我的打印机」→「下载 printer-agent」对话框中的 Windows 入口(v1.0.27),下载 printer-agent-setup-1.0.27.exe 并双击运行。本教程主要面向 Linux 部署。

8. 配置 conf/config.toml

所有运行时行为都通过 conf/config.toml 控制。下面逐项说明每个字段。

[printer]

[printer]
ipp_addr = "ipp://192.168.1.139:631/ipp/print"   # IPP 目标地址,agent 收到的 PDF 任务会投递给这里

[remote]

[remote]
addr = "wss://your-printhub-host.example.com"   # 必填,WebSocket 基址,必须以 ws:// 或 wss:// 开头
# download_addr = "https://your-printhub-host.example.com"   # 可选;省略时按 addr 推导

[agent]

[agent]
token = "phb.<owner_uuid>.<secret>"   # 必填,第 3 节签发的 token
# pong_timeout = 60        # 心跳超时(秒),默认 60
# reconnect_base_ms = 1000 # 首次重连延迟(毫秒),默认 1000
# reconnect_max_ms = 30000 # 重连延迟上限(毫秒),默认 30000

[log]

[log]
path = "log/printer-agent.log"   # 相对工作目录,建议指向独立挂载点
level = "info"                   # trace / debug / info / warn / error
frag_size = 1024                 # 单个日志分片大小(KB)
frag_num = 10                    # 保留的分片数量
frag_gzip = false                # 是否对旧分片做 gzip 压缩

9. 以守护进程方式运行

配置完成后,使用 -d 标志启动常驻进程。注意:printer-agent 没有任何 daemon 子命令,必须使用顶层的 -d / --daemon 标志。

printer-agent -d
# 等价:
printer-agent --daemon

使用非默认配置路径printer-agent -d --config /etc/printer-agent/config.toml

前台调试printer-agent -d -v # 同时开启 verbose 日志,输出到 stderr 与日志文件

10. 使用 systemd 托管

DEB 包未附带 systemd 单元。把下面内容保存为 /etc/systemd/system/printer-agent.service,然后启用:

[Unit]
Description=PrintHub printer-agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=printer-agent
Group=printer-agent
ExecStart=/usr/local/printer-agent/bin/printer-agent -d --config /usr/local/printer-agent/conf/config.toml
Restart=always
RestartSec=5

# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/log/printer-agent /usr/local/printer-agent/log

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now printer-agent
sudo systemctl status printer-agent

11. 验证与排障

启动后按下列顺序核对:

  • 日志路径下的 printer-agent.log 中应出现「start daemon」「WebSocket connected」「identify → status=online」之类的字样;
  • printhub-host 侧能在「我的打印机」中看到设备状态变为「在线」;
  • 本地执行 printer-agent --show-printer 能正确返回 IPP 属性,说明打印机可达;
  • 提交一份测试打印任务,观察「打印记录」中状态从「等待」→「打印中」→「已完成」。

常见问题

  • 启动后立刻 401:检查 config.toml 中 [agent].token 前后是否有多余空白;token 是否完整复制了 phb.<owner>.<secret> 三段。
  • 反复重连但始终未注册:printhub-host 数据库中 owner 已被删除或 token 已被 revoke,需要在「我的打印机」中重新签发。
  • 任务下发后报 IPP 错误:先用 printer-agent --show-printer 验证打印机可达;检查防火墙是否放行了 UDP/TCP 631。
  • 下载的 PDF 任务文件以 { 或 [ 开头:任务文件已损坏或权限失效,请到「打印记录」中查看错误详情并重新提交;agent 会在日志中打印前 256 字节用于排障。
  • 日志出现 download_url is empty:printhub-host 找不到打印机对应的 token,请执行 printhub-host regenerate-printer-token <printer_id> 重新签发。

12. 卸载与升级

  • DEB 包:sudo dpkg -r printer-agent,会同时移除 /usr/bin 下的符号链接。
  • Docker:docker rm -f printer-agent;如不再需要镜像可一并 docker image rm。
  • 源码:直接删除构建产物(dist/、target/)与可执行文件即可。
  • 升级前请先停服(systemctl stop printer-agent 或 docker stop printer-agent),替换二进制后重新启动。新版本配置文件如无字段变更可继续使用旧 config.toml。

13. 协议参考

agent 与 host 之间通过 JSON 信封通信,协议版本 1.0。完整的帧类型、字段说明与安全考量请参考 printhub-host 仓库的 docs/AGENT_REGISTRATION.md 第 8 节与第 9 节。