Docker Desktop for Mac の container のログを空にする

Docker Desktop for Mac で container のログを空にする方法の紹介です。
執筆時の環境は Docker Desktop for Mac 3.2.2(61853) です。

前置き

docker inspect を実行すると、container のログファイルのパスを取得できます。

$ docker inspect CONTAINER_ID --format "{{.LogPath}}" /var/lib/docker/containers/3d0305c254c33ff5e78d675f45e60fdcef65937ed8b53e21baf07f818d34ce9b/3d0305c254c33ff5e78d675f45e60fdcef65937ed8b53e21baf07f818d34ce9b-json.log
Code language: JavaScript (javascript)

Linux 上で dockerd や containerd が docker container と同じホストで動いている場合は、以下のようなコマンドを実行することでログを空にできます。

$ sudo truncate $(docker inspect CONTAINER_ID --format "{{.LogPath}}") --size 0 $ sudo bash -c ":> $(docker inspect CONTAINER_ID --format "{{.LogPath}}")"
Code language: JavaScript (javascript)

しかし、macOS の Docker Desktop for Mac で docker inspect を実行すると、ログファイルのパスは取得できますが、macOS 上には /var/lib/docker がないので、上記の方法ではログを空にできません。
これは、macOS 上の HyperKit という仮想化環境で LinuxKit という軽量 Linux を動かし、そのうえで containerd を動かしているためです(雑な図にしたものが以下です)。

+------------+ | containerd | +------------+ | LinuxKit | +------------+ | HyperKit | +------------+ | macOS | +------------+

Docker Desktop for Mac 環境で container のログを空にしたい場合、macOS ではなく LinuxKit 上のログファイルを空にする必要があります。

LinuxKit への接続

https://docs.docker.com/docker-for-mac/release-notes/#docker-desktop-community-2400 を見ると以下のコマンドで shell を開けると書かれています。

$ nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock
Code language: JavaScript (javascript)

接続する方法がわかれば、あとはログを空にするコマンドを nc にパイプで渡せば OK です。
ただし、このとき LinuxKit 上では docker コマンドを実行できないので、macOS 上でログファイルのパスを取得します。

$ echo ":> $(docker inspect CONTAINER_ID --format '{{.LogPath}}'); exit" | nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock
Code language: JavaScript (javascript)

しかし、これを毎回実行するのは面倒ですので、shell の関数を定義しておくと良いです。

clear_docker_logs() { echo ":> $(docker inspect ${1} --format '{{.LogPath}}'); exit" | nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock }
Code language: JavaScript (javascript)

引数に渡した container ID のログを空にできます。
docker-compose を使っている場合は docker-compose ps -q CONTAINER_NAME の結果を渡すような関数を用意しておくと良さそうです。
brewnetcat を install していると nc -U が使えなくてエラーが発生するので注意してください。そのときは、/usr/bin/nc と絶対パスで入力すれば OK です。

参考

https://gist.github.com/BretFisher/5e1a0c7bcca4c735e716abf62afad389socatscreen でシリアル接続する例が書かれていました。LinuxKit 上で色々やるときはこちらのほうが操作しやすいかもしれません。

Leave a Reply