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

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

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


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

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


这两种方法都可以正确设置时区! >谁知道会给什么?

评论

如果您使用Alpine,则需要先安装tzdata,请参见github.com/gliderlabs/docker-alpine/issues/136

仅供参考。 。 。我希望在Docker运行时而不是docker build / dockerfile时设置容器的时区。使用-v / etc / localtime:/ etc / localtime:ro(CentOS)之类的作品。内部容器命令行日期以预期的时区格式返回日期。但是在容器中运行的詹金斯认为时区是UTC。为什么? / etc / localtime是建立容器中../usr/share/zoneinfo/UTC的符号链接。容器中UTC文件的内容现在是新时区。但是jenkins(也许还有其他基于Java的软件)使用的符号链接的名称仍然是“ UTC”。寻找解决方案。 。 。

需要两件事:1.创建容器时,使用init脚本设置/ etc / localtime symlink和/ etc / timezone; 2.对于jenkins时区来自两个java选项,这些选项需要传递给init脚本。开始詹金斯进程。例如“ -Dorg.apache.commons.jelly.tags.fmt.timeZone = America / New_York -Duser.timezone = America / New_York”。抱歉,这是针对詹金斯的,但希望对其他詹金斯用户有用。

#1 楼

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


评论


TZ名称列表:en.wikipedia.org/wiki/List_of_tz_database_time_zones

–比利汤姆
17年8月14日在9:19

在Ubuntu:16.04(可能还有其他版本)上,您需要安装tzdata软件包才能使其正常工作。

–Opsse
17-10-23在1:29

我是唯一认为在Dockerfile中对时区进行硬编码不是很聪明的人吗?

–沃尔夫冈
18年2月2日在15:39



@Wolfgang这是一个示例。您可以通过通常提供环境变量的任何其他方式来提供它,例如命令行,docker-compose.yml等。

–迈克尔·汉普顿
18年2月2日在15:42

我注意到,至少对于基于Alpine的图像,只需设置TZ变量就足够了。我不必设置符号链接或其他任何东西。

– code_dredd
19年6月21日在21:54

#2 楼

通常,只需在docker容器中设置一个环境变量就可以了,如下所示:

评论


这似乎是最优雅的方法。请注意,某些基本映像(例如ubuntu:16.04)没有应在Dockerfile中添加的tzdata软件包。

–朱利安·法斯特(JulienFastré)
17年5月19日在10:25

+1-我同意朱利安;这似乎是在运行时设置时区的最优雅的方法。这在CentOS上运作良好。 Alpine映像确实需要安装'tzdata'软件包,在构建时它比harcoding配置更可取,除非无法容忍额外的3MB映像有效负载:)

–分心
17年12月27日在16:09

这似乎很好,但似乎对我不起作用(使用CentOS 7.5.1804和tzdata-2018e-3.el7.noarch)?悲伤的脸

–gaoithe
19年1月21日在17:19

#3 楼

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

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

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


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

评论


如果您的CentOS分布式主机在重新启动容器之前输入命令echo“ Europe / Paris”> / etc / timezone。

–CrazyMax
17年9月18日在13:21



在MacOS主机上可以使用吗?

– Redsandro
17-10-26在23:24

在MAC中不起作用

– Marcello de Sales
18年1月19日,3:08

这曾经可以在MacOS上使用,但很长一段时间后我才再次尝试,得到了以下内容。不知道是High Sierra还是docker更改引起的:“ docker:来自守护程序的错误响应:挂载被拒绝:OS X不共享路径/ etc / localtime,并且Docker不知道。 >首选项...->文件共享。有关更多信息,请参阅docs.docker.com/docker-for-mac/osxfs/#namespaces。

–gae123
18 Mar 4 '18 at 2:22

因为/ etc / localtime是一个符号链接,所以这将破坏您的zoneinfo db(因此/ usr / share / zoneinfo / Some / Thing可能会在容器内挂载为/ usr / share / zoneinfo / UTC)。更不用说您将主机中的db文件与容器中的db文件混合了。

–ionelmc
18年5月10日在15:03

#4 楼

在映像中安装/etc/localtime,使其与host -v同步,是最受欢迎的一种。

,但请参见问题12084:当软件要求设置文件/etc/timezone时,它不起作用。
这样,您将其用作默认值etc/UTC

我确定实际上没有万无一失的优雅在docker容器中设置时区的一种方法。
因此,最终解决了这个问题:

App 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行代码即可。


评论


对我来说是:RUN echo“ Europe / London”> / etc / timezone

– jpmottin
17-10-19在11:54



@jpmottin那么在serverfault.com/a/856593/783中又是什么呢?

–VonC
17-10-19在12:01

#5 楼

在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


评论


说真的...这是唯一有效的解决方案!

– Gerrat
17年6月30日在22:13

还必须这样做-默认情况下,似乎tzdata在某些发行版中不再存在。

–彼得
18年1月24日在7:06

#6 楼

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

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


#7 楼

在这里加两分钱,是因为我尝试了其中的几分钱,但在基于高山的图像上却没有用。 >
[来源]

#8 楼

感谢VonC提供信息并链接到该问题。这看起来像是一个混乱的混乱局面,因此我对如何解决此问题的想法进行了一些测试,而且效果很好。选择我的时区)

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


然后我更新了Dockerfile来反映这一点:

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


这有点不对劲,因为它似乎太容易被忽视了……还是可以接受?

评论


这也是我尝试过的方法,但是退出容器后,时区仍然会自行重置。这是在Debian上。

–迈克·张伯伦
17年6月9日在4:57

@MikeChamberlain您是否碰巧尝试了上述迈克尔·汉普顿的已接受答案?我自己还没有实现它,但是我认为这是考虑它收到的支持意见的方法。

– ock猴
17年9月9日17:00

#9 楼

在Alpine基本映像中(示例使用node:10.16.0-alpine):




FROM node:10.16.0-alpine

ENV TZ=America/Los_Angeles

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

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm i --production

COPY . .

CMD node index.js



#10 楼

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`


评论


如果您的基本映像是alpine(5MB)(未安装“ tzdata”),则无济于事

–max4ever
19年6月21日在14:05