TL; DR
Docker で CUPS サーバーのコンテナと CUPS クライアントのコンテナを作成し、クライアントから印刷を実行する。
動機
- CUPS(Common Unix Printing System) の概要はわかっているつもりだが、実のところ使いこなしている感じがない。(印刷できていれば深入りしない状態、その代わり応用が利かない)
- Docker で帳票印刷の部分を分離できれば、プリンター本体が変更されてもアプリサーバーの CUPS を変更しなくてもよいのでは?
- cupsd ってデーモンだから、クライアントと分離できるはずだ。
Dockerfile
CUPS サーバー
エプソンのプリンタを使っているため printer-driver-escpr をインストールしている。単に CUPS とエプソン用のドライバーだけがインストールしてあるイメージとコンテナを作成。
FROM debian:latest
RUN apt-get update && apt-get upgrade && apt-get install -y \
cups printer-driver-escpr && \
sed -i 's!Listen localhost:631!Listen 0.0.0.0:631!' /etc/cups/cupsd.conf && \
sed -i 's!Browsing Off!Browsing On!' /etc/cups/cupsd.conf && \
sed -i 's!<Location />!<Location />\n Allow All!' /etc/cups/cupsd.conf && \
sed -i 's!<Location /admin>!<Location /admin>\n Allow All\n Require user @SYSTEM!' /etc/cups/cupsd.conf && \
sed -i 's!<Location /admin/conf>!<Location /admin/conf>\n Allow All!' /etc/cups/cupsd.conf && \
echo "ServerAlias *" >> /etc/cups/cupsd.conf && \
echo "DefaultEncryption Never" >> /etc/cups/cupsd.conf &&\
useradd -r -G lpadmin -M print && \ # 注意
echo print:print | chpasswd && \ # 注意
systemctl enable cups
CMD ["/sbin/init"]
※ CUPS 用にユーザーネーム; print 、パスワード; print をハードコーディングしてるので実装では注意されたし。
CUPS クライアント
Alpine Linux に cups クライアントだけをインストールしてあるイメージとコンテナを作成。
FROM alpine:latest
RUN apk --no-cache update && apk --no-cache upgrade && apk --no-cache add cups-client &&\
mkdir /etc/cups && \
echo 'ServerName IPAddress' > /etc/cups/client.conf
Dockerfile が作成できたらコンテナを立ち上げ。
docker build -t cupsd_epson -f Dockerfile.server .
docker run -dit -p 6631:631 --name epson cupsd_epson
docker inspect epson | grep IPAddress
割り当てられた IPAddress を把握しておく(ここでは172.17.0.2)
ブラウザで localhost:6631 からプリンターの設定を手作業でする。その際、"共有"にマークする(lpadmin -p プリンタ名 -o printer-is-shared=true
相当)その後、
docker build -t cups_client -f Dockerfile.client .
docker run -it --name client -v $(pwd):/home cups_client /bin/sh
/etc/cups/client.conf
の IPAddress
部分を 172.17.0.2
に書き換える( vi がデフォルトでインストール済み)。要するにどの CUPS サーバーで印刷するかを指定しておく。
実践
lpr -P PRINTER test.pdf
PRINTER
はプリンタ名。test.pdf
は適切に用意する。ヴォリュームをマウントしてあるので/home
から使えるようになっている。
後記
- Alpine ではうまくエプソンのドライバーをビルドできなかった。
- macOS では /etc/cups/client.conf は deprecated らしい。client.conf(5)
- ServerName は1つしか指定できない(最後の ServerName のみ)なので、複数の印刷機があったら1つの CUPS サーバーにぶら下げるしかないのかな?
-
CMD ["/sbin/init"]
よりCMD ["/usr/sbin/cupsd", "-f"]
の方がいいかも。 - docker network を使う場合は
client.conf
をどう書けばよいのやら。アドレス固定しかないのか? - いっそ各ネットワークプリンターに CUPS を搭載すればよいのに。