TrumanWong

Docker时区调整方案

TrumanWong
8/6/2022

背景

大部分Docker镜像都是基于AlpineUbuntuDebianCentOS等基础镜像制作而成,这些镜像都采用的UTC时间,与我们的北京时间整整相差8小时。时区问题是十分重要的,时间不统一,业务会乱套。

运行Docker容器时调整时区

Linux系统中,控制时区和时间的主要有两处:

  • /etc/timezone:主要代表当前时区设置,一般链接指向/usr/share/zoneinfo目录下的具体时区。
  • /etc/localtime:主要代表当前时区设置下的本地时间。

通用docker时区修改方案

我们可以直接将宿主机上的/etc/timezone/etc/localtime挂载到容器中,这样可以保持容器和宿主机时区和时间一直。

-v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro

范例如下:

$ sudo docker run --name time-demo --rm -it -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro debian /bin/bash
# date -R
Sat, 06 Aug 2022 21:53:49 +0800

通过传递环境变量改变容器时区

该方案只适应于基于DebianCentOS基础镜像制作的Docker镜像,不适应于AlpineUbuntu基础镜像制作的Docker镜像。

对于DebianCentOS镜像制作的Docker镜像,在运行容器时,通过传递-e TZ=Asia/Shanghai参数,实现修改容器时区的效果:

-e TZ=Asia/Shanghai

使用范例如下:

$ sudo docker run --name time-demo -it -e TZ=Asia/Shanghai debian /bin/bash
# date -R
Sat, 06 Aug 2022 21:59:16 +0800

制作Docker镜像时调整时区

编写Dockerfile文件,构建自己的Docker镜像,可以一劳永逸解决时区问题。

Alpine

通过查阅官方文档,我们可以将以下代码添加到Dockerfile中:

ENV TZ Asia/Shanghai

RUN apk add tzdata && cp /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone \
    && apk del tzdata

Debian

Debian基础镜像中已经安装了tzdata包,因此可以将以下代码添加到Dockerfile中:

ENV TZ=Asia/Shanghai \
    DEBIAN_FRONTEND=noninteractive

RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone \
    && dpkg-reconfigure --frontend noninteractive tzdata \
    && rm -rf /var/lib/apt/lists/*

Ubuntu

Ubuntu基础镜像中没有安装tzdata包,因此需要先安装tzdata包。代码如下:

ENV TZ=Asia/Shanghai \
    DEBIAN_FRONTEND=noninteractive

RUN apt update \
    && apt install -y tzdata \
    && ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone \
    && dpkg-reconfigure --frontend noninteractive tzdata \
    && rm -rf /var/lib/apt/lists/*

CentOS

CentOS镜像中已经安装tzdata包,代码如下:

ENV TZ Asia/Shanghai

RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone