Docker 容器时间和时区(不会反映变化)

Cho*_*key 221 timezone date docker

Docker 容器从哪里获取时间信息?我已经从基本的 ubuntu:trusty 映像创建了一些容器,当我运行它并请求“日期”时,我得到了 UTC 时间。

有一段时间我通过在我的 Dockerfile 中执行以下操作来解决这个问题:

RUN sudo echo "America/Los_Angeles" > /etc/timezone
Run Code Online (Sandbox Code Playgroud)

但是,由于某种原因停止工作。在网上搜索我看到以下建议:

docker run -v /etc/timezone:/etc/timezone [image-name]
Run Code Online (Sandbox Code Playgroud)

不过,这两种方法都正确设置了时区!

$ cat /etc/timezone
America/Los_Angeles
$ date
Tue Apr 14 23:46:51 UTC 2015
Run Code Online (Sandbox Code Playgroud)

有谁知道是什么给的?

Mic*_*ton 327

这里的秘密是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
Run Code Online (Sandbox Code Playgroud)

作为奖励,TZ 也将在容器中正确设置。

这也是与发行版无关的,因此它几乎适用于任何 Linux。

注意:如果您使用的是基于 alpine 的映像,则必须安装第tzdata一个。(在此处查看此问题)

看起来像这样:

RUN apk add --no-cache tzdata
ENV TZ America/Los_Angeles
Run Code Online (Sandbox Code Playgroud)

  • TZ 名称列表:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones (35认同)
  • 使用 Ubuntu:16.04(可能还有其他版本),您需要安装 `tzdata` 包才能使其正常工作。 (10认同)
  • 我是唯一一个认为在 Dockerfile 中对时区进行硬编码不是很聪明的人吗? (9认同)
  • 我注意到,至少对于基于 Alpine 的图像,只需设置 `TZ` 变量就足够了。我不必设置符号链接或其他任何东西。 (4认同)
  • @Wolfgang 这是一个例子。您可以以通常提供环境变量的任何其他方式提供它,例如命令行、docker-compose.yml 等。 (2认同)

Vic*_*los 102

通常在 docker 容器中设置一个环境变量就足够了,如下所示:

docker run -e TZ=Europe/Amsterdam debian:jessie date
Run Code Online (Sandbox Code Playgroud)

当然,这也适用于docker-compose.

  • 这似乎是最优雅的方式。注意一些基础镜像,比如 `ubuntu:16.04`,没有应该添加到 Dockerfile 中的 `tzdata` 包。 (7认同)
  • +1 -- 我同意朱利安的观点;这似乎是在运行时设置时区的最优雅的方法。这适用于 CentOS。Alpine 图像确实需要安装“tzdata”包,这在构建时优于硬编码配置,除非不能容忍额外的 3MB 图像负载:) (2认同)

小智 32

您可以将本地文件(/etc/timezone 和 /etc/localtime)添加为 docker-container 中的卷。

docker-compose.yml使用以下几行更新您的。

volumes:
    - "/etc/timezone:/etc/timezone:ro"
    - "/etc/localtime:/etc/localtime:ro"
Run Code Online (Sandbox Code Playgroud)

现在容器时间与主机上的相同

  • 这会破坏您的 zoneinfo 数据库,因为 /etc/localtime 是一个符号链接(因此 /usr/share/zoneinfo/Some/Thing 可能会在容器内挂载为 /usr/share/zoneinfo/UTC)。更不用说您将来自主机的 db 文件与容器中的文件混合在一起。 (4认同)
  • 不适用于 MAC (2认同)
  • 警告:这可能会导致奇怪的错误!请参阅 https://github.com/nodejs/node/issues/28743。至少你也应该挂载`/usr/share/zoneinfo`。 (2认同)

Von*_*onC 22

安装/etc/localtime在图像中,因此与它同步host -v是最流行的一种。

但请参阅问题 12084

这是不正确的,因为当软件需要/etc/timezone设置文件时它不起作用。
您使用的这种方式将其保留为默认值etc/UTC

我已经确定实际上没有万无一失的优雅方式来设置 docker 容器内的时区。
所以最终确定了这个解决方案:

应用泊坞窗文件:

# Relocate the timezone file
RUN mkdir -p /config/etc && mv /etc/timezone /config/etc/ && ln -s /config/etc/timezone /etc/
Run Code Online (Sandbox Code Playgroud)

应用程序入口点脚本:

# Set timezone as specified in /config/etc/timezone
dpkg-reconfigure -f noninteractive tzdata
Run Code Online (Sandbox Code Playgroud)

数据量/configdockerfile,本地化到特定国家或地区:

# Set the time zone
RUN echo "Europe/London" > /config/etc/timezone
Run Code Online (Sandbox Code Playgroud)

...这并不优雅,因为涉及 3 个单独的文件,并/etc/localtime在每个运行时容器启动时重新创建。这是比较浪费的。

但是它确实可以正常工作,并成功地实现了基本应用程序映像和每个国家/地区的本地化配置之间的分离。
在 3 行代码中。

  • 对我来说,它是:`RUN echo "Europe/London" > /etc/timezone` (2认同)

小智 17

在 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
Run Code Online (Sandbox Code Playgroud)

  • 说真的……这是唯一有效的解决方案! (2认同)

Xia*_*lin 6

如果您使用基于以下内容的 docker 映像ubuntu

# Change the docker default timezone from UTC to SGT
echo "Asia/Singapore" > /etc/timezone
dpkg-reconfigure tzdata
date
Run Code Online (Sandbox Code Playgroud)


小智 5

在这里添加我的两分钱,因为我已经尝试了其中的几种,但没有一个适用于基于高山的图像。

然而,这却成功了:

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/*
Run Code Online (Sandbox Code Playgroud)

[来源]