Docker容器内时间和宿主机不一致修复
前言
Docker容器里的时间和宿主机差了8个小时,日志时间不对,定时任务也跑偏。本文讲怎么修复容器时区问题。
一、问题现象
# 宿主机时间
date
# 输出:Thu Oct 8 08:14:01 CST 2026
# 容器里时间
docker exec 容器名 date
# 输出:Thu Oct 8 00:14:01 UTC 2026
差了8个小时,因为容器默认用UTC时区。
二、查看容器时区
docker exec 容器名 date
或者:
docker exec 容器名 cat /etc/timezone
三、修复方法
方法1:挂载时区文件(推荐)
启动容器时挂载宿主机的时区文件:
docker run -v /etc/localtime:/etc/localtime:ro 镜像名
这样容器就和宿主机用同一个时区了。
方法2:设置环境变量
docker run -e TZ=Asia/Shanghai 镜像名
方法3:进容器手动改
# 进容器
docker exec -it 容器名 bash
# 装时区数据
apt-get update && apt-get install -y tzdata
# 设置时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
# 验证
date
方法4:Docker Compose设置
在docker-compose.yml里加:
services:
app:
image: xxx
environment:
- TZ=Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro
四、PHP容器额外设置
PHP的时区和系统时区是两回事,还要改php.ini:
[Date]
date.timezone = Asia/Shanghai
或者在代码里设:
<?php
date_default_timezone_set('Asia/Shanghai');
?>
五、MySQL容器额外设置
MySQL的时区也要改:
-- 查看当前时区
SELECT @@global.time_zone;
-- 设置为东八区
SET GLOBAL time_zone = '+8:00';
永久生效改my.cnf:
[mysqld]
default-time-zone = '+8:00'
六、验证
# 宿主机时间
date
# 容器时间
docker exec 容器名 date
两个时间一致就对了。
常见坑
坑1:改了时区不生效
改了时区文件,重启容器又变回UTC了。
原因: 容器重启后文件系统重置了。
解决: 用挂载的方式,不要进容器改。
坑2:只改了系统时区,PHP时区不对
系统时间对了,但PHP date()还是错的。
原因: PHP有自己的时区设置。
解决: 改php.ini的date.timezone。
坑3:日志时间不对
日志里的时间还是UTC。
原因: 程序启动时读的时区,改了时区要重启程序。
解决: 重启容器或重启程序。
坑4:Windows/Mac Docker Desktop
Windows和Mac上Docker Desktop的时区处理不一样。
解决: 直接用TZ环境变量最稳。
坑5:时区列表找不到Asia/Shanghai
原因: 容器里没装tzdata。
解决: 先装tzdata:
apt-get install -y tzdata
总结
最稳的方法:
- 挂载
/etc/localtime:/etc/localtime:ro - 加环境变量
TZ=Asia/Shanghai - PHP改
date.timezone - MySQL改
default-time-zone
记住: 时区不一致是Docker最常见的问题之一,部署完第一件事先验证时间。
遇到问题加QQ23979811 协助处理