Dockerコンテナのタイムゾーンの変更は環境変数を設定すればいいと思っている方へ

コンテナのタイムゾーンはデフォルトではだいたいUTC(協定世界時)になってるんですが、これをJST(日本標準時)に変更したい場合、よく知られている方法として

$ docker run -e TZ=Asia/Tokyo hoge

というように環境変数TZを設定してやればいいというのがあります。ただしAlpine Linuxはこれだけではうまくいきません。

実験

dockerイメージalpine:3.6でコンテナを作ります。そしてdateコマンドを実行します。

mbp2016:~ shibujibu$ docker run alpine:3.6 date
Mon Aug 28 05:44:58 UTC 2017
mbp2016:~ shibujibu$ docker run -e TZ=Asia/Tokyo alpine:3.6 date
Mon Aug 28 05:45:02 GMT 2017
mbp2016:~ shibujibu$ 

タイムゾーンGMT(グリニッジ標準時)になってる???

原因

答えはほとんどここのQiitaの記事に書いてあります

qiita.com

AlpineにはUbuntuとかCentOSみたいなディストリと違って/usr/share/zoneinfoが存在しません。

mbp2016:~ shibujibu$ docker run -it alpine:3.6 /bin/sh
/ # ls /usr/share/
apk   man   misc
/ # 

というわけでLinuxのTime Zone Databaseをインストールします。

/ # apk --update add tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.6/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.6/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2017a-r0)
Executing busybox-1.26.2-r5.trigger
OK: 7 MiB in 12 packages
/ # ls /usr/share/
apk       man       misc      zoneinfo
/ # export TZ=Asia/Tokyo
/ # date
Mon Aug 28 15:52:41 JST 2017
/ # 

おお!JSTになった!

ちなみにfluent/fluentdなんかはベースイメージがAlpine Linuxなので注意です。

DockerでEFKの環境を作って、fluentdのコンテナでTZが異なる外部ホストのrsyslogからデータを取得していた時、kibanaでsyslogのデータのtimestampを見たら未来の時間になってました。fluentdのTZをJSTにしたら解決しましたね。