Docker for Mac で container のログを空にする方法の紹介です。
執筆時の環境は Docker for Mac 18.06.1-ce-mac73 (26764) です。
前置き
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 for Mac で docker inspect を実行すると、ログファイルのパスは取得できますが、macOS 上には /var/lib/docker
がないので、上記の方法ではログを空にできません。
これは、macOS 上の HyperKit という仮想化環境で LinuxKit という軽量 Linux を動かし、そのうえで containerd を動かしているためです(雑な図にしたものが以下です)。
+------------+ | containerd | +------------+ | LinuxKit | +------------+ | HyperKit | +------------+ | macOS | +------------+
Docker for Mac 環境で container のログを空にしたい場合、macOS ではなく LinuxKit 上のログファイルを空にする必要があります。
LinuxKit への接続
LinuxKit には screen でシリアル接続します。
$ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# Ctrl-d を入力すると、以下が出力されます(Ctrl-a + k -> y でコンソールから抜けられます)
Welcome to LinuxKit
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""___/ ===
{ / ===-
______ O __/
__/
___________/
linuxkit-025000000001 login: root (automatic login)
Welcome to LinuxKit!
NOTE: This system is namespaced.
The namespace you are currently in may not be the root.
System services are namespaced; to access, use `ctr -n services.linuxkit ...`
login[7397]: root login on 'ttyS0'
Code language: PHP (php)
ただ、LinuxKit 上では docker コマンドを実行できないので、macOS 上でログファイルのパスを取得します。取得後に LinuxKit 上で以下を実行すればログを空にできます。
$ :> /path/to/logfile
Code language: JavaScript (javascript)
しかし、これを毎回実行するのは面倒ですので、shell の関数を定義しておくと良いです。
clear_docker_log() {
local container_id="${1}"
logfile=$(docker inspect $container_id --format "{{.LogPath}}")
screen_name="docker_$(date +%s)"
# LinuxKit にシリアル接続(detached screen として)
screen -d -m -S ${screen_name} ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# ログを空にするコマンドを送信
# 末尾の echo は Enter キー入力のエミュレート
screen -S ${screen_name} -p 0 -X stuff $":> ${logfile}"$(echo -ne '\015')
# シリアル接続を閉じる
screen -S ${screen_name} -X quit
}
Code language: PHP (php)
引数に渡した container ID のログを空にできます。
docker-compose を使っている場合は docker-compose ps -q CONTAINER_NAME の結果を渡すような関数を用意しておくと良さそうです。