Ubuntu の Docker コンテナでタイムゾーンを変更したい
Docker で Ubuntu を特に何もせず立てたときはタイムゾーンが UTC になりますが、日本に住んでいて日本時間で日常生活を送っている私にとっては、やはりコンテナ上のタイムゾーンも JST のほうがログとかの取り回しがしやすいので、 JST にする方法をいろいろ試していたのですが試行錯誤したログです。
ちなみに普通に立ち上げた時はやはり UTC でした。
% docker run --rm -i -t ubuntu:xenial
root@b4eb0482f2cb:/# date
Wed Jun 7 04:25:42 UTC 2017
著名な方法の1つとして、 /etc/localtime
をマウントするといった方法 があり、この方法だと Docker Hub から落としてきたイメージをそのままつかうことができるので、ビルドの必要もありません。
しかしながら手元の環境1だとなぜかマウントしても変わらなかったことと、タイムゾーンを変更したいコンテナがオリジナルのコンテナだったこともあり、 Dockerfile 内でコンテナビルド中に変更することにしました。
Ubuntu 14.04 だとわりと簡単にできていた
コンテナで立ち上げる Ubuntu が 14.04(trusty) の場合だと以下の Dockerfile で変更できていました。
FROM ubuntu:trusty
ENV TZ Asia/Tokyo
RUN echo "${TZ}" > /etc/timezone \
&& dpkg-reconfigure -f noninteractive tzdata
% docker build --tag ubuntu-jst:trusty -f Dockerfile.ubuntu_trusty .
:
% docker run --rm -i -t ubuntu-jst:trusty
root@4fbcbb5f70c4:/# date
Wed Jun 7 21:10:54 JST 2017
しかしながら、同じ方法で ubuntu:xenial をベースにするとコケてしまいます。
% docker build --tag ubuntu-jst:xenial -f Dockerfile.ubuntu_xenial .
Sending build context to Docker daemon 5.12 kB
Step 1/3 : FROM ubuntu:xenial
---> 7b9b13f7b9c0
Step 2/3 : ENV TZ Asia/Tokyo
---> Running in 1d3359c286c7
---> cfb72b2e99e6
Removing intermediate container 1d3359c286c7
Step 3/3 : RUN echo "${TZ}" > /etc/timezone && dpkg-reconfigure -f nonintractive tzdata
---> Running in 1d964b6a380c
debconf: unable to initialize frontend: Nonintractive
debconf: (Can't locate Debconf/FrontEnd/Nonintractive.pm in @INC (you may need to install the Debconf::FrontEnd::Nonintractive module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at (eval 19) line 2.)
debconf: falling back to frontend: Noninteractive
dpkg-query: package 'tzdata' is not installed and no information is available
Use dpkg --info (= dpkg-deb --info) to examine archive files,
and dpkg --contents (= dpkg-deb --contents) to list their contents.
/usr/sbin/dpkg-reconfigure: tzdata is not installed
何が原因なのか
エラーメッセージに書いてあるとおり、 Docker Hub 上にある Ubuntu のイメージに tzdata
コマンド自体がそもそも入っていないことが原因です。そもそも Ubuntu は 16.04 から systemd になっている影響で、本来であれば timedatectl
でタイムゾーンを設定するべきなので、そのせいもありデフォルトで入ってないのかもしれません2。
がんばれば Docker で systemd を扱う方法もないことはないので、これによって timezonectl
を使うことができるのかもしれませんが、タイムゾーンの変更のためだけに systemd を導入するのは、お菓子を袋をあけるために日本刀を用意するようなものです。
少々話がそれたましたが、一応 tzdata
は、まだ apt-get
で入れることができるようなのでありがたくパッケージ管理システムによって得た堕落を享受することにします。
FROM ubuntu:xenial
# パッケージ取得先のミラーをjaistに変更する
RUN sed -i.bak -e "s%http://archive.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g" /etc/apt/sources.list
ENV TZ Asia/Tokyo
RUN apt-get update \
&& apt-get install -y tzdata \
&& rm -rf /var/lib/apt/lists/* \
&& echo "${TZ}" > /etc/timezone \
&& rm /etc/localtime \
&& ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata
これで JST の Ubuntu コンテナを用意することができました。
% docker build --tag ubuntu-jst:xenial -f Dockerfile.ubuntu_xenial .
:
% docker run --rm -i -t ubuntu-jst:xenial
root@2646f266e8d1:/# date
Wed Jun 7 21:41:08 JST 2017