题 Docker Container时间和时区(不会反映更改)


Docker容器在哪里获取时间信息?我已经从基本的ubuntu创建了一些容器:可信赖的图像,当我运行它并请求'date'时,我得到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

谁知道是什么给出的?


73
2018-04-14 23:49




如果你使用 Alpine,你需要安装 tzdata 首先,看到这里 github.com/gliderlabs/docker-alpine/issues/136 - Belter


答案:


这里的秘密是 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

124
2018-04-17 19:55



TZ名称列表: en.wikipedia.org/wiki/List_of_tz_database_time_zones - BillyTom
使用Ubuntu:16.04(也许还有其他版本)你需要拥有 tzdata 安装包以使这项工作。 - Opsse


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

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

当然这也适用 docker-compose


30
2018-01-13 22:15



这似乎是最优雅的方式。小心一些基本形象,如 ubuntu:16.04,没有 tzdata 应该在Dockerfile中添加的包。 - Julien Fastré
+1 - 我同意朱利安;这似乎是在运行时设置时区的最优雅方法。这适用于CentOS。 Alpine图像确实需要安装'tzdata'软件包,除了不能容忍额外的3MB图像有效负载外,它比构建时的编码配置更受欢迎。 - Frelling


安装 /etc/localtime 在图像中,它与...同步 host -v 是最受欢迎的一个。

但是看 问题12084

它不正确,因为当软件需要而不是文件时它不起作用 /etc/timezone 要设置。
  这样你就可以将它作为默认值 etc/UTC

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

应用程序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行代码中。


16
2018-04-15 06:14



对我来说,它是: RUN echo "Europe/London" > /etc/timezone - jpmottin
@jpmottin所以有点像 serverfault.com/a/856593/783 然后? - VonC


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

更新你的 docker-compose.yml 有以下几行。

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

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


10
2018-06-08 15:55



如果您在CentOS distrib主机上输入命令 echo "Europe/Paris" > /etc/timezone 在重新启动容器之前。 - CrazyMax
这适用于MacOS主机吗? - Redsandro
在MAC中不起作用 - Marcello de Sales
这曾经在MacOS上工作,但我在很长一段时间后再次尝试它,我得到以下内容。不确定High Sierra或docker更改是否导致这种情况:“docker:来自守护程序的错误响应:安装被拒绝:路径/ etc / localtime不是从OS X共享的,并且Docker不知道。您可以从Docker配置共享路径 - >首选项... - >文件共享。请参阅 docs.docker.com/docker-for-mac/osxfs/#namespaces 了解更多信息。“ - gae123
这将破坏您的zoneinfo数据库,因为/ etc / localtime是一个符号链接(因此/ usr / share / zoneinfo / Some / Thing很可能在容器内作为/ usr / share / zoneinfo / UTC挂载)。更不用说你将主机的db文件与容器中的db文件混合在一起。 - ionelmc


在ubuntu 16.04图像中有bug。解决方案是

    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

8
2018-06-19 10:12



说真的......这是唯一有效的解决方案! - Gerrat
还必须这样做 - 似乎默认情况下tzdata不再出现在某些发行版中。 - Peter


如果您使用基于的docker镜像 ubuntu :

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

3
2017-07-16 03:37





感谢VonC提供的信息和链接。这看起来像是一个令人费解的混乱,所以我对自己如何解决这个问题的想法做了一些测试,看起来效果很好。

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

(按照提示选择我的时区)

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

然后我更新了我的Dockerfiles来反映这个:

FROM chocko/ubuntu:local

这肯定有问题,因为它似乎太容易被忽视......或者这是否可以接受?


2
2018-04-15 19:10



这也是我尝试过的,但是时区 仍然 在我之后重置自己 exit 容器。这是在Debian上。 - Mike Chamberlain
@MikeChamberlain你碰巧尝试过迈克尔汉普顿接受的答案吗?我自己没有实现它,但我认为这是考虑它收到的赞成票的方式。 - Chockomonkey