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

总结

最稳的方法:

  1. 挂载 /etc/localtime:/etc/localtime:ro
  2. 加环境变量 TZ=Asia/Shanghai
  3. PHP改 date.timezone
  4. MySQL改 default-time-zone

记住: 时区不一致是Docker最常见的问题之一,部署完第一件事先验证时间。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:14