跳过正文
  1. 文章/

在 Synology NAS 上通过 CUPS Docker 实现 AirPrint

作者
Yang Hu

在 Synology NAS 上配置 AirPrint 的操作手册,让 iOS/macOS 设备可以通过局域网打印到 USB 或网络打印机。使用 Docker CUPS 容器和 Synology 内置的 avahi(mDNS)守护进程实现服务发现。

架构
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
iPhone
  │  mDNS 发现 (_ipp._tcp)
Synology avahi-daemon(eth4,端口 5353)
  │  从 /etc/avahi/services/ 读取服务文件
CUPS Docker 容器(host 网络模式,端口 631)
  │  生成 /etc/avahi/services/AirPrint-*.service
  │  将打印任务代理到打印机
打印机(如 socket://10.0.20.50:9100)

关键设计决策:

  • 容器使用 network_mode: host — mDNS 广播必须如此
  • 容器直接挂载 /etc/avahi/services,让 Synology 的 avahi 读取其服务文件
  • 必须禁用 Synology 自带的 CUPS,以释放端口 631

前置条件
#

  • 已安装 Docker(Container Manager)的 Synology DSM
  • NAS 的 SSH 访问权限
  • 打印机可从 NAS 访问(USB 或网络 socket)
  • 禁用 Synology 内置 CUPS 打印服务(通过 DSM 软件包或 synoservicectl

配置步骤
#

1. 创建目录结构
#

1
mkdir -p /volume1/docker/cups/config

2. docker-compose.yaml
#

创建 /volume1/docker/cups/docker-compose.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
version: '3'
services:
  cups-airprint:
    image: tigerj/cups-airprint:latest
    container_name: cups-airprint
    network_mode: "host"
    environment:
      - CUPSADMIN=admin
      - CUPSPASSWORD=yourpassword
    volumes:
      - /volume1/docker/cups/config:/config
      - /etc/avahi/services:/services   # 让容器管理 avahi 服务文件
    restart: unless-stopped

3. 启动容器
#

1
2
cd /volume1/docker/cups
docker-compose up -d

4. 通过 CUPS Web UI 添加打印机
#

在浏览器中打开 http://<nas-ip>:631,用管理员凭据登录后添加打印机:

  • Administration → Add Printer
  • 网络打印机:socket://10.0.x.x:9100
  • 设置 Shared: Yes
  • 选择合适的 PPD/驱动(Gutenprint 对大多数 Brother/HP 打印机兼容性好)

容器的 printer-update.sh 脚本会监听 CUPS 打印机变化,并自动重新生成 /etc/avahi/services/ 中的 avahi 服务文件。

5. 验证 mDNS 广播
#

1
2
avahi-browse -a -t | grep -i airprint
# 应显示:AirPrint <PrinterName> @ Synology   _ipp._tcp   local

6. 验证 CUPS 可访问
#

1
2
curl http://<nas-ip>:631/printers/
# 应列出你的打印机,状态为 Idle

排障记录
#

编辑 yaml 后容器使用了错误的卷挂载
#

编辑 docker-compose.yaml 修改 /services 挂载后,必须重新创建容器(而不仅仅是重启)才能生效:

1
docker-compose down && docker-compose up -d

验证当前挂载:

1
2
docker inspect cups-airprint --format '{{json .Mounts}}'
# /services 目标的 Source 应为 /etc/avahi/services

iOS 上找不到打印机
#

按顺序检查:

  1. avahi-browse -a -t | grep ipp — 服务是否正在广播?
  2. curl http://nas-ip:631/printers/ — CUPS 是否在提供打印机服务?
  3. 防火墙 — DSM 防火墙可能阻止设备子网访问端口 631
  4. docker inspect cups-airprint — 确认 network_modehost
  5. 强制 iOS 重新扫描:关闭/开启 Wi-Fi,或打开某 App 的打印对话框

avahi 只在一个接口广播
#

检查 /etc/avahi/avahi-daemon.conf — Synology 将 avahi 锁定到 allow-interfaces=eth4(主 LAN 口)。单网卡设置下这是正确的。如果你的 LAN 在其他接口,更新该行(但 DSM 升级后可能重置)。

端口 631 已被占用
#

Synology 的 CUPS 可能仍在运行。停止它:

1
2
synoservicectl --stop cups
synoservicectl --stop cups-lpd   # 如有

我的配置
#

项目
NASSynology DS1621+
NAS IP10.0.10.10
打印机Brother HL-2270DW
打印机 IPsocket://10.0.20.50:9100
驱动Brother HL-2250DN - CUPS+Gutenprint v5.2.11
Docker 镜像tigerj/cups-airprint:latest
avahi 接口eth4

备注
#

  • avahi 服务文件中的 URF=none TXT 记录对于使用传统 CUPS 驱动的老式打印机是正常现象 — iOS 仍然可以发现并使用该打印机
  • avahi 服务文件在容器启动和任意 CUPS 打印机状态变化时自动重新生成,无需手动编辑
  • docker-compose.yaml 是唯一事实来源 — 修改卷配置后始终重新创建(而非重启)容器