前言

如果在启动Docker容器的过程中没有单独配置localtime,很可能造成Docker容器时间与主机时间不一致的情况,比如UTC和CST相差8小时,换句话来说就是容器时间与北京时间相差8个小时。

更新历史

2020年08月13日 - 初稿

阅读原文 - https://wsgzao.github.io/post/docker-localtime/


问题描述

问题:容器时间与北京时间相差8个小时

1
2
3
4
5
6
7
8
# 查看主机时间
[root@localhost ~]# date
2020年07月27日 星期三 22:42:44 CST

# 查看容器时间
# docker exec -it <containerid> /bin/sh
root@b43340ecf5ef:/# date
Wed Jul 27 14:43:31 UTC 2020

原因:宿主机设置了时区,而Docker容器并没有设置,导致两者相差8小时

可以发现,他们相隔了8小时

CST应该是指(China Shanghai Time,东八区时间)
UTC应该是指(Coordinated Universal Time,标准时间)
所以,这2个时间实际上应该相差8个小时

所以,必须统一两者的时区

解决方案

docker run 添加时间参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-v /etc/localtime:/etc/localtime

# 实例1
docker run -p 3306:3306 --name mysql -v /etc/localtime:/etc/localtime

# 实例2
docker run \
--detach \
--restart always \
--name 'scribe' \
--publish 11315:11315 \
--mount type=bind,source=/data/gop/,destination=/data/gop/,consistency=consistent \
-v /etc/localtime:/etc/localtime \
wsgzao/facebook-scribe

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
# 方法1
# 添加时区环境变量,亚洲,上海
ENV TimeZone=Asia/Shanghai
# 使用软连接,并且将时区配置覆盖/etc/timezone
RUN ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone

# 方法2
# CentOS
RUN echo "Asia/shanghai" > /etc/timezone
# Ubuntu
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

docker-compose

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#第一种方式(推荐):
environment:
TZ: Asia/Shanghai

#第二种方式:
environment:
SET_CONTAINER_TIMEZONE=true
CONTAINER_TIMEZONE=Asia/Shanghai

#第三种方式:
volumes:
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime

宿主机直接执行命令给某个容器同步时间

1
2
3
4
5
6
# 方法1:直接在宿主机操作
docker cp /etc/localtime 【容器ID或者NAME】:/etc/localtime
docker cp -L /usr/share/zoneinfo/Asia/Shanghai 【容器ID或者NAME】:/etc/localtime

# 方法2:登录容器同步时区timezone
ln -sf /usr/share/zoneinfo/Asia/Singapore /etc/localtime

在完成后,再通过date命令进行查看当前时间
但是,在容器中运行的程序的时间不一定能更新过来,比如在容器运行的mysql服务,在更新时间后,通过sql查看mysql的时间

select now() from dual;

可以发现,时间并没有更改过来
这时候必须要重启mysql服务或者重启docker容器,mysql才能读取到更改过后的时间

文章目录
  1. 1. 前言
  2. 2. 更新历史
  3. 3. 问题描述
  4. 4. 解决方案
    1. 4.1. docker run 添加时间参数
    2. 4.2. Dockerfile
    3. 4.3. docker-compose
    4. 4.4. 宿主机直接执行命令给某个容器同步时间