大多数场景下,直接通过环境变量设置时区是最轻量且兼容性的方案,若容器内应用强依赖系统本地时间文件,则需挂载宿主机时间配置。
先说结论:优先使用环境变量 TZ 指定时区,特殊需求再挂载 localtime 文件。
- 适合:大多数应用服务、CI/CD 流程、无状态容器
- 先准备:确认宿主机时间准确、明确应用对时区的依赖方式
- 验收:进入容器执行 date 命令核对显示时间
命令速用版
启动容器时直接传入环境变量:
docker run -d -e TZ=Asia/Shanghai nginx
或者使用卷挂载宿主机时间配置:
docker run -d -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro nginx
为什么会这样
容器共享宿主机的内核,系统时钟(UTC)是一致的。差异主要在于用户空间的时区配置。容器镜像默认可能包含 UTC 时区信息,导致显示时间与宿主机不一致,进而影响日志时间戳或定时任务。
分步处理
1. 确认宿主机时间状态
在宿主机执行以下命令,确保宿主机时间本身是准确的:
timedatectl
2. 选择配置方式
方式一:环境变量(推荐)
在 docker-compose.yml 中添加环境变量配置:
services:
app:
image: my-app
environment:
- TZ=Asia/Shanghai
方式二:文件挂载
若应用读取本地时间文件,需挂载以下两个文件:
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
注意添加:ro 参数以只读方式挂载,防止容器内误修改。
3. 重启容器使配置生效
配置修改后,必须重启容器才能加载新的时间配置。
怎么验证是否生效
进入容器内部执行日期命令:
docker exec -it <容器 ID> date
对比输出时间与宿主机是否一致。同时检查应用日志中的时间戳是否符合预期。
常见坑
1. 只挂载 localtime 未挂载 timezone:部分应用读取 timezone 文件判断时区,缺失可能导致解析错误。
2. Java 应用特殊处理:部分旧版 Java 应用可能不识别 TZ 环境变量,需额外添加 JVM 参数 -Duser.timezone=Asia/Shanghai。
3. 权限问题:挂载文件时建议加:ro 只读权限,避免容器内误修改影响宿主机。
4. 定时任务偏差:若容器内运行 cron 服务,需确保时区同步后再配置 cron 表达式,否则执行时间会偏移。
参考来源
- Docker 官方文档 - Environment Variables
- Linux 手册页 - localtime, timezone