# 时区设置

容器系统时间默认为 UTC 协调世界时间 (Universal Time Coordinated),与本地所属时区 CST (上海时间)相差 8 个小时。当需要获取系统时间用于日志记录、数据库存储等相关操作时,容器内时区不一致问题将会带来一系列困扰。

在构建基础镜像或在基础镜像的基础上制作自定义镜像时,在 Dockerfile 中创建时区文件即可解决单一容器内时区不一致问题,且后续使用该镜像时,将不再受时区问题困扰。

# 前期判断

首先需要判断自己的 FROM 镜像是什么系统,来确定接下来执行的步骤是什么。

举个例子,一个 dockerfile 文件内容如下:

FROM node:12-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "node", "index.js" ]

我们可以通过在自己电脑安装docker,运行如下命令查看

# node:12-slim替换成自己的
docker pull node:12-slim
docker run -it node:12-slim bash
# 进入容器内部
cat /etc/issue

就可以看到此镜像对应的系统类型

Debian GNU/Linux 9 \n \l

如果你已经部署了一次服务在微信云托管中,可以前往服务进入实例,运行以下命令,也可以查看到对应的类型。

如果你的 Dockerfile 中有多个FROM,则取最后一次出现的 FROM 来判断。

# 添加时区命令

按照上一步骤确定的系统,选择下述正确的命令添加到你原有 Dockerfile 中CMD上面,在FROMCMD之间,如果你的构建过程中有用到时区,则在需要时区的命令之前添加。

# 1. Alpine

alpine比较精简,需要安装tzdata,可以将你自己的安装步骤与下属步骤合并

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

如果报超时等错误,需要在前面配置软件源,添加如下代码

set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

如果设置完时区仍然不对,请删除最后的 apk del tzdata 重新打包上传

# 2. Debian

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/*

上述例子中,就变成如下:

FROM node:12-slim
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/*
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
CMD [ "node", "index.js" ]

# 3. Ubuntu

Ubuntu 基础镜像中没有 tzdata 包,所以下述命令使用 apt 安装了一下,如果你的原有 dockerfile 中有 apt 安装步骤,需要整合一下代码。

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/*

# 4. CentOS

ENV TZ Asia/Shanghai

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

# 总结

设置好时区后,可以使用下述命令测试一下

date
### 原来 >>> Mon Mar 14 02:36:27 UTC 2022
### 修改 >>> Mon Mar 14 10:36:16 CST 2022

上述方法如果有不适用,可以在官方交流群联系我们。