Dockerコンテナの時間とタイムゾーン(変更は反映されません)


135

Dockerコンテナーは時間情報をどこで取得しますか?基本的なubuntu:trustyイメージからいくつかのコンテナーを作成し、それを実行して「日付」を要求すると、UTC時間を取得します。

しばらくの間、Dockerfileで次の操作を行うことでこれを回避しました。

RUN sudo echo "America/Los_Angeles" > /etc/timezone

ただし、何らかの理由で機能しなくなりました。オンラインで検索すると、以下が提案されました:

docker run -v /etc/timezone:/etc/timezone [image-name]

ただし、これらのメソッドは両方ともタイムゾーンを正しく設定します!

$ cat /etc/timezone
America/Los_Angeles
$ date
Tue Apr 14 23:46:51 UTC 2015

誰が何を与えるのか知っていますか?


3
を使用する場合はAlpinetzdata最初にインストールする必要があります。こちらをご覧くださいgithub.com/gliderlabs/docker-alpine/issues/136
Belter

1
ご参考までに 。。。コンテナのタイムゾーンをdocker build / dockerfile時ではなく、docker実行時に設定したい。使用し-v /etc/localtime:/etc/localtime:roた作品の(CentOSの)ソート。内部コンテナのコマンドライン日付は、予想されるタイムゾーン形式で日付を返します。しかし、コンテナで実行されているジェンキンスはタイムゾーンがUTCであると考えています。どうして?/ etc / localtimeは、ビルドされたコンテナ内の../usr/share/zoneinfo/UTCへのシンボリックリンクです。コンテナ内のUTCファイルのコンテンツが新しいタイムゾーンになりました。しかし、ジェンキンス(およびおそらく他のJavaベースのソフトウェア)は、まだ「UTC」であるシンボリックリンクの名前を使用します。ソリューションを検索しています。。。
1

1
2つのことが必要です。1。コンテナの作成時にinitスクリプトを使用して/ etc / localtimeシンボリックリンクと/ etc / timezoneを設定し、2。jenkinsのタイムゾーンが2つのJavaオプションから取得される場合jenkinsプロセスを開始します。例: "-Dorg.apache.commons.jelly.tags.fmt.timeZone = America / New_York -Duser.timezone = America / New_York"。おApび申し上げますが、これはジェンキンス固有ですが、他のジェンキンスユーザーにとっては便利です。
1

回答:


208

ここでの秘密は、のファイルへのコピー、ハードリンク、またはシンボリックリンク(シンボリックリンクが推奨されます)としてdpkg-reconfigure tzdata作成/etc/localtimeされるだけです/usr/share/zoneinfo。したがって、Dockerfileから完全にこれを行うことができます。考慮してください:

ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

また、ボーナスとして、TZもコンテナーに正しく設定されます。

これはディストリビューションにも依存しないため、ほとんどすべてのLinuxで機能します。

注:高山ベースのイメージを使用している場合は、tzdata最初にインストールする必要があります。(ここでこの問題を参照してください)

次のようになります。

RUN apk add --no-cache tzdata
ENV TZ America/Los_Angeles


5
Ubuntu:16.04(および他のバージョン)を使用するにはtzdata、この作業を行うためにパッケージをインストールする必要があります。
-Opsse

5
Dockerfileにタイムゾーンをハードコーディングするのはあまり賢くないと思うのは私だけですか?
ウルフギャング

1
@Wolfgangこれは一例です。あなたは、通常、このようなコマンドラインなどの環境変数、ドッキングウィンドウ-compose.ymlなどを提供する他の方法でそれを提供することができます
マイケル・ハンプトン

少なくともAlpineベースの画像では、TZ変数を設定するだけで十分であることに気付きました。シンボリックリンクなどを設定する必要はありませんでした。
code_dredd

58

通常、次のように、Dockerコンテナーに環境変数を設定するだけで十分です。

docker run -e TZ=Europe/Amsterdam debian:jessie date

もちろん、これはでも動作しdocker-composeます。


2
これが最もエレガントな方法のようです。のような一部のベースイメージにはubuntu:16.04tzdataDockerfileに追加する必要があるパッケージがないことに注意してください。
ジュリアンファスト

1
+1-ジュリアンに同意します。これは、実行時にタイムゾーンを設定するための最もエレガントなアプローチのようです。これはCentOSでうまく機能します。余分な3メガバイトの画像ペイロードを許容することができない場合を除きアルパインの画像は:)ビルド時にharcoding設定より優先される「のtzdata」パッケージのインストールを必要としない
Frelling

これは良いように見えますが、私にとってはうまくいかないようです(CentOS 7.5.1804およびtzdata-2018e-3.el7.noarchを使用)?悲しそうな顔
1

22

/etc/localtimeイメージにマウントするので、同期host -vが最も一般的なものです。

ただし、問題12084を参照してください。

ソフトウェアが代わりにファイル/etc/timezoneを設定する必要がある場合は機能しないため、正しくありません。
そのように使用すると、デフォルト値のままになりますetc/UTC

実際には、ドッカーコンテナー内にタイムゾーンを設定する確実なエレガントな方法はないと判断しました。
だから最終的にこのソリューションに落ち着きました:

アプリdockerfile:

# Relocate the timezone file
RUN mkdir -p /config/etc && mv /etc/timezone /config/etc/ && ln -s /config/etc/timezone /etc/

アプリエントリポイントスクリプト:

# Set timezone as specified in /config/etc/timezone
dpkg-reconfigure -f noninteractive tzdata

/config特定の国または地域にローカライズされたデータボリュームdockerfile:

# Set the time zone
RUN echo "Europe/London" > /config/etc/timezone

... 3つの別個のファイルが関係/etc/localtimeし、ランタイムコンテナの開始ごとに再作成されるため、エレガントではありません。これはかなり無駄です。

ただし、適切に機能し、ベースアプリのイメージと国ごとのローカライズされた構成を適切に分離します。
3行のコード。


1
私にとっては、 RUN echo "Europe/London" > /etc/timezone
jpmottin

だから、ビットのように@jpmottin serverfault.com/a/856593/783、その後?
VonC

18

docker-containerで、ローカルファイル(/ etc / timezoneおよび/ etc / localtime)をボリュームとして追加できます。

docker-compose.yml次の行で更新します。

volumes:
    - "/etc/timezone:/etc/timezone:ro"
    - "/etc/localtime:/etc/localtime:ro"

コンテナ時間はホストと同じです


CentOS distribホストでecho "Europe/Paris" > /etc/timezoneコンテナを再起動する前にコマンドを入力します。
CrazyMax

これはMacOSホストで動作しますか?
レッサンドロ

MACで動作しません
マルチェロドゥ販売

以前はMacOSで動作していましたが、久しぶりにもう一度試したところ、次のようになりました。High Sierraまたはdockerの変更が原因かどうかわからない:「docker:デーモンからのエラー応答:マウントが拒否されました:パス/ etc / localtimeはOS Xから共有されず、Dockerには認識されません。Dockerから共有パスを構成できます- >設定...- >ファイル共有。詳細については、docs.docker.com / docker- for - mac / osxfs /#namespacesを参照してください。
gae123

1
/ etc / localtimeはシンボリックリンクであるため、これによりzoneinfo dbが破損します(したがって、/ usr / share / zoneinfo / Some / Thingはコンテナー内で/ usr / share / zoneinfo / UTCとしてマウントされる可能性があります)。ホストからのdbファイルとコンテナ内のdbファイルを混在させることは言うまでもありません。
ionelmc

12

ubuntu 16.04イメージにはバグがあります。解決策は

    ENV TZ 'Europe/Tallinn'
    RUN echo $TZ > /etc/timezone && \
    apt-get update && apt-get install -y tzdata && \
    rm /etc/localtime && \
    ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata && \
    apt-get clean

1
真剣に...これが唯一の解決策です!
ジェラート

1
また、これを行わなければなりませんでした-tzdataはデフォルトでは一部のディストリビューションに含まれていないようです。
ピーター

4

に基づいてドッカー画像を使用している場合ubuntu

# Change the docker default timezone from UTC to SGT
echo "Asia/Singapore" > /etc/timezone
dpkg-reconfigure tzdata
date

3

情報と問題へのリンクについてVonCに感謝します。これは非常に複雑な混乱のように思えるので、これを解決する方法について自分のアイデアでテストを行いましたが、うまくいくようです。

>docker run -it ubuntu:trusty /bin/bash
#dpkg-reconfigure tzdata

(プロンプトに従ってタイムゾーンを選択します)

>docker commit [container-id] chocko/ubuntu:local

次に、これを反映するようにDockerfilesを更新しました。

FROM chocko/ubuntu:local

見落とすのは簡単すぎるように思われるので、これには何か間違っているはずです...または、これは受け入れられますか?


これも私が試したものですが、コンテナの後、タイムゾーン自動的にリセットさexitれます。これはDebian上にあります。
マイクチェンバレン

@MikeChamberlainは、マイケル・ハンプトンが受け入れた上記の答えを試してみましたか?私自身は実装していませんが、受け取った賛成票を検討する方法だと思います。
Chockomonkey

2

ここに私の2セントを追加します。これらのいくつかを試しましたが、高山ベースの画像では動作しませんでした。

しかし、これはトリックをしました:

ENV TZ=America/Toronto
RUN apk update
RUN apk upgrade
RUN apk add ca-certificates && update-ca-certificates
RUN apk add --update tzdata
RUN rm -rf /var/cache/apk/*

[ ソース ]


1

docker run引数にタイムゾーンを設定するより一般的な方法:

-e TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

または再利用:

function GET_TZ () {
    ls -la /etc/localtime | cut -d/ -f8-9
}

...
-e TZ=`GET_TZ`

ベースイメージが「tzdata」がインストールされていないalpine(5MB)の場合は役に立ちません
max4ever
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.