_ [debian] Canon LBP3100 in Docker

いろいろ 諦めて Windows で使ってた Canon LBP3100。Docker ならもうちょっと何とかなりそうな気がしたので、挑戦してみた。結論から言うと成功。使ったドライバのバージョンは CAPT Printer Driver for Linux Ver.2.71。 ホスト側は

  • Debian GNU/Linux (unstable)
  • Linux 4.16.0-2-amd64
  • Docker CE 18.03.1~ce-0

Dockerfile:

FROM ubuntu:16.04

ENV DEBIAN_FRONTEND noninteractive

COPY deb/cndrvcups-*_amd64.deb /root/

RUN dpkg --add-architecture i386 \
	&& apt-get update \
	&& apt-get install -y --no-install-recommends \
		cups \
		libatk1.0-0 \
		libglade2-0 \
		libgtk2.0-0 \
		libpopt0 \
		xauth \
		cups-bsd \
		libc6:i386 \
		libstdc++6:i386 \
		libxml2:i386 \
	&& ln -s /lib/i386-linux-gnu/liblzma.so.5.0.0 \
		/lib/i386-linux-gnu/liblzma.so.2 \
        && dpkg -i /root/cndrvcups-*_amd64.deb \
	&& rm -f /usr/lib/cups/backend/parallel \
	&& rm -f /usr/lib/cups/backend/serial \
        && apt-get clean \
        && rm -rf /var/lib/apt/lists/*

RUN useradd -u 1000 -d /home/XXXX -m -s /bin/bash XXXX

COPY cupsd.conf /etc/cups/
COPY entrypoint.sh /

ENTRYPOINT [ "/entrypoint.sh" ]

cupsd.conf:

LogLevel warn
PageLogFormat
MaxLogSize 0
Listen 0.0.0.0:631
Listen /var/run/cups/cups.sock
Browsing Off
BrowseLocalProtocols dnssd
DefaultAuthType Basic
WebInterface Yes
DefaultEncryption Never
<Location />
  Order allow,deny
  Allow 172.17.0.1
</Location>
<Policy default>
  JobPrivateAccess default
  JobPrivateValues default
  SubscriptionPrivateAccess default
  SubscriptionPrivateValues default
  <Limit All>
    Order allow,deny
    Allow 172.17.0.1
  </Limit>
</Policy>

entrypoint.sh:

#!/bin/sh

/etc/init.d/cups start

lpadmin -p LBP3100 -m CNCUPSLBP3100CAPTJ.ppd -v ccp://localhost:59687 -E
ccpdadmin -p LBP3100 -o /dev/usb/lp0
/etc/init.d/ccpd start

/bin/sleep infinity

起動スクリプト:

#!/bin/sh

docker run -ti --rm --name lbp3100 \
	-v /dev:/dev \
	--privileged \
	\
	-v /tmp/.X11-unix:/tmp/.X11-unix \
	-e DISPLAY=$DISPLAY \
	--ipc host \
	\
	-v /home/XXXX:/home/XXXX:ro \
	-v /tmp:/var/tmp:ro \
lbp3100

印刷スクリプト:

#!/bin/sh

file=$1

echo $file | grep -q ^/tmp/
if [ $? = 0 ]; then
  file="/var$file"
fi

docker exec -ti lbp3100 su - XXXX -c "cngplp -p $file"

ポイントとしては

  • cupsd と ccpd は印刷するときだけ起動する使い捨て。起動しっぱなしにしない。なので cups の認証とかは一切考えない。
  • コンテナ内で印刷 GUI を起動してホスト側に飛ばす。これも通信とか認証とか考えない。
  • cups パッケージだけでなく cups-bsd パッケージも必要(内部で lpr コマンドを使っている)。
  • 64bit ドライバと言ってるのに 32bit バイナリが入っている(ファイルが存在してるのに bash: /usr/bin/captmoncnab9: No such file or directory となることで気がついた)。
  • liblzma.so.2 を要求するけど存在しないので symlink で誤魔化す。

これで印刷のために Windows を起動する手間が省けた。