DockerコンテナからRICOHの複合機に印刷物を飛ばしてみる
電子化(DX?)を進めていても, どうしてもまだ紙で処理しなければいけないものってありますよね.
せめて印刷作業だけでも自動化して可能な限り省力化したいなー, という思いで複合機へのプリントを自動化 & Dockerコンテナ化してみたので共有します.
オフィスに RICOH の複合機(プリンター)があって同じような境遇の方(ニッチすぎる😂)は是非参考にどうぞ.
RICOH に限らず Linux 用の PPD のドライバが配布されているプリンタであれば真似(流用)できると思いますので, 自動印刷に興味が有る方は挑戦してみてください.
今回は今私の手元にある RICOH IM C300
を例に記しますが, RICOH MP C3004
RICOH IM C5510
等でも本手順で動作確認できています.
なお今回使用しているドライバはこちらです.
対応機種に含まれていれば機種を問わず流用できるはずです.
Docker を使用せずにシンプルに Linux から複合機を使用する際の参考としても, どうぞご活用ください(主に Dockerfile
cmd.sh
run.sh
辺り).
また, 以前書いた LaTeX による文書ジェネレータと組み合わせるとより統括的(?)なシステムが作れそうな気がしますね.
前提
- Docker環境が構築されている
- シェル環境がある
- MacOS または Linux 環境であるか, Windows であれば WSL 環境であること
- ただし Apple silicon 搭載 Mac の場合は一部スクリプトが動作せず(印刷自体には支障なし. 後述.)
- MacOS または Linux 環境であるか, Windows であれば WSL 環境であること
- シェル環境がある
やり方
Dockerfile を書く
まずは Dockerfile を書きます.
FROM ubuntu:latest
LABEL maintainer="example@exmaple.com"
# COPY . /opt
WORKDIR /opt
ADD ./docker/run.sh /run.sh
ADD ./docker/cmd.sh /cmd.sh
RUN /run.sh
CMD ["/cmd.sh"]
この Dockerfile
では大したことはしてなくて, このあと書くファイルをコピーしたり叩いたりしているだけです.
真似して使う場合は maintainer
に自分のメールアドレスを設定してビルドしてください.
ちなみに, タグが latest
なのでいつか動かなくなるかもしれません.
気になる方はタグを固定するのがよいと思います.
欲を言うと alpine
のようなもっと軽量なイメージを使いたいですね(弄る余裕がなくて...).
次にDockerコンテナ用のファイルを置くディレクトリを掘ります.
好みの問題なので別に掘らなくてもいいですが, その場合は適宜パスを直してください.
mkdir docker
ついでに印刷物を置くディレクトリも作成します.
mkdir docs_to_print
touch ./docs_to_print/.gitkeep # git にコミットする場合はディレクトリが消えないようにしておきます
次にDockerコンテナ用のスクリプトを書きます.
#!/bin/bash
set -exuo pipefail
apt -y update
apt -y install lpr cups cups-client cups-pdf
apt -y install xfonts-base xfonts-75dpi 'fonts-takao-*'
apt -y install curl inotify-tools
## 予めdockerディレクトリにダウンロードしておく場合
# tar -zxvf ./docker/Ricoh-Basic-PS-PPDv1.12.2.tar.gz
## 都度ダウンロードする場合
curl -LOJ 'https://op-drv-ds1.support.ricoh.com/seresBB/servlet/VSORPageDownloadServlet' \
--data-raw 'PATH=w%2Fbb%2Fpub_j%2Fdr_ut_d%2F4101013%2F4101013911%2FV1122%2F5244035%2FRicoh-Basic-PS-PPDv1.12.2.tar.gz&FWID_U001=WRU001&NWID_U001=&TEST_001=&buttonName=Accept'
tar -zxvf ./Ricoh-Basic-PS-PPDv1.12.2.tar.gz
useradd -r -G lpadmin -M print
echo print:print | chpasswd
mkdir -p /opt/docs_to_print
このスクリプトは Dockerfile
の RUN
, つまり docker build
フェーズで実行されるものです.
- lpr/cups などプリンタとの通信をするためのパッケージを入れています
- xfonts-base xfonts-75dpi 'fonts-takao-*' などは日本語が最低限きれいに印刷されるようにフォントを入れています. 好みに応じて変更してください.
#!/bin/bash
set -exuo pipefail
mkdir -p /etc/cups
echo "${PRINTER_NAME} ${PRINTER_IP}" > /etc/cups/client.conf
service lpd start
service cups start
DRIVER_DIR=Ricoh-Basic_PSv1.12.2
# カラー用
# DRIVER_PPD=Ricoh-Basic_PS_Color.ppd
# モノクロ用
DRIVER_PPD=Ricoh-Basic_PS_B_W.ppd
DRIVER_PPD_PATH=/opt/${DRIVER_DIR}/${DRIVER_PPD}
# NOTE: Windows PC とかでは使ってない項目だけどここ以外に任意文字列を入れられる場所が見つからない
sed -i "s|^[\*]*DefaultUserID.*$|*DefaultUserID: Custom.${PRINTER_USER}|" $DRIVER_PPD_PATH
# NOTE: これは効いてなさそう
# sed -i "s|^[\*]*DefaultLoginID.*$|*DefaultLoginID: Custom.${PRINTER_USER}|" $DRIVER_PPD_PATH
sed -i "s|^[\*]*DefaultJobPassword.*$|*DefaultJobPassword: Custom.${PRINTER_PW}|" $DRIVER_PPD_PATH
sed -i "s|^[\*]*DefaultJobType.*$|*DefaultJobType: LockedPrint|" $DRIVER_PPD_PATH
lpadmin -p $PRINTER_NAME -E -v "ipp://${PRINTER_IP}/ipp/print" -P $DRIVER_PPD_PATH$DRIVER_PPD_PATH
export TERM=xterm
rm ./docs_to_print/.gitkeep
# 以下, docs_to_print ディレクトリへのファイル追加を検知して自動で印刷を行うデモです
# NOTE: Apple silicon の qemu 仮想下では inotify 系の API は動作しない
# 同じようなことがしたければ Python とかで書けば良いと思う
inotifywait -m -e create --format '%w%f' -r ./docs_to_print | \
while read file_path; do
echo "Printing ${file_path}"
lp -d $PRINTER_NAME -oColorModel=Gray $file_path
echo 'Removing...'
rm $file_path
echo 'Done.'
# TODO: WEBHOOK通知したい.
# sleep 60
done
このスクリプトは Dockerfile
の CMD
なので, docker run
時に実行されるものです.
lpd
と cups
の start
は RUN
ではなく CMD
である必要があります.
- 印刷関係のサービスを起動し, ドライバの設定をして複合機を登録しています
- 各環境変数(
${VALUE}
/$VALUE
)はdocker run
時に流し込みます - 最後に,
inotifywait
でディレクトリを監視し, ファイルが追加されたら自動で複合機に送信する処理をしています-
ただし, Apple silicon 搭載 Mac の Docker 環境では
inotifywait
が動作しません.- シェルで頑張らずとも, Python などで印刷コマンドを発行するなどワークアラウンド手段はいくらでもありますPythonからの印刷コマンド発行例
import subprocess # ... cmd = 'lp -d RICOH_IM_C300 -oColorModel=Gray sample.pdf' try: subprocess.check_call(cmd.split()) except Exception as e: pass # ...
- シェルで頑張らずとも, Python などで印刷コマンドを発行するなどワークアラウンド手段はいくらでもあります
-
ただし, Apple silicon 搭載 Mac の Docker 環境では
最後に環境変数のファイルを設置します.
PRINTER_NAME=RICOH_IM_C300
PRINTER_IP=192.0.2.1
# 半角8文字以内に収めること
PRINTER_USER=docker
# 4-8文字の数字であること
PRINTER_PW=1234
ファイル名に特に深い意味はないです.
docker run
時に --env-file
で渡して使います.
ここまでを通して, 下記のような構成になっていたら正解です.
% tree
.
├── .env
├── Dockerfile
├── docker
│ ├── cmd.sh
│ └── run.sh
└── docs_to_print
docker run してみる
(ちなみに最近は docker run
よりも docker container run
のほうが良いらしいですね)
docker build -t print-on-docker .
docker run -d -it --restart=always \
--name print-on-docker \
--env-file .env \
-v $PWD/docs_to_print:/opt/docs_to_print \
print-on-docker
起動できたら適宜ログを確認してみてください.
docker logs -f print-on-docker
下記のようにサンプルファイルをディレクトリに置いてあげると実際に複合機に飛ばされます
(ログを見ているならターミナルの別窓から叩いてください)
cp ./sample.pdf ./docs_to_print/
複合機を見に行くと docker さんから印刷物が届いています!
LockedPrint にしたので暗証番号が求められますね! (๑•̀ㅂ•́)و✧ヨシッ!
当たり前ですが崩れもなくしっかり印刷できました!
以上です. 「いかがだったでしょうか?」とか言わないんで, 誰かの何かの役に立てば嬉しいです. 👋🏻
Discussion