dockerコマンドをcronで実行させたら「入力デバイスがTTYじゃ無いよ」と怒られた件

cronでdockerコマンドを定期実行していたのですが、うまく実行されていないことに気づきました。

https://hodalog.com/how-to-inspect-cron-logs/

↑の記事に沿ってログを調査したところ、 docker container exec コマンドの使い方が間違っていました。

正しく動作するよう修正したのでメモします。

結論

cronのエラーログには「the input device is not a TTY」という文字が残されていました。

cronでは次のコマンドを実行させています。

docker container exec -it CONTAINER_ID certbot renew

上記コマンドから -it というオプションを外し、修正しました。

docker container exec CONTAINER_ID certbot renew

結果、正常に動作しました。やったね!

TTYとは

ちょっと正しく理解できているのか怪しいのですが、調べたなりの情報をまとめます。

TTYはもともとコマンドラインでの操作やコマンドの出力結果を対話的に行うためのインターフェースのこと。

通常、私たちがCLI越しにコマンドを叩いたり、結果を見たりする場合は「TTYの中にいる状態」。

Jenkinsやcronでのコマンド実行はTTYが無い状態で行われるため、TTYを必要とするコマンドの実行に失敗する。ということみたいです。

dockerコマンドの -t オプションは「TTYを割り当ててくれる」オプション。

このオプションを外すことでcronジョブが正常に実行できるようになります。

ついでに -i は「標準入力を開き続ける」オプションで、これもCLIでコンテナを操作するために必要なオプション。

これがないとコンテナに入って色々操作できないので、ユーザーがターミナル開いてなんかしたいときは必要なオプションなのですが、cronとかjenkinsでのジョブ実行には不要です。

まとめ

「とりあえずこうすると動く」的な発想でコマンドを覚えていると、応用が効かなくなるパティーンですね!

でも調べるとキリがないため、こういうタイミングで少しずつ調査するというスタンスで良いのではないかと思いますね。