Docker容器中文乱码与时区设置完整方法 Docker
前言
容器里经常出现两个问题:中文显示成问号或乱码,以及容器时间比宿主机差 8 小时。原因是基础镜像默认使用 POSIX locale 且 UTC 时区,而业务需要 zh_CN.UTF-8 和东八区。本文给出 Dockerfile 设置、运行时挂载、compose 配置三种解决方式,一次解决乱码和时间。
操作步骤
1. 查看容器当前 locale 和时间
docker exec -it 容器名 locale
docker exec -it 容器名 date
2. 运行时直接指定环境变量(最快)
docker run -d --name app \
-e LANG=zh_CN.UTF-8 \
-e TZ=Asia/Shanghai \
镜像名
3. Dockerfile 中固化
FROM debian:bookworm
ENV LANG=zh_CN.UTF-8
ENV TZ=Asia/Shanghai
RUN apt update && apt install -y locales tzdata \
&& locale-gen zh_CN.UTF-8 \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
4. 挂载宿主机时区文件
docker run -d -v /etc/localtime:/etc/localtime:ro --name app 镜像名
5. Docker Compose 配置
services:
app:
image: 镜像名
environment:
LANG: zh_CN.UTF-8
TZ: Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro
6. 重建并验证
docker compose up -d
docker exec -it app date
docker exec -it app locale
时间显示东八区、locale 为 zh_CN.UTF-8 即成功。
常见坑
- 基础镜像没装 locales,只设 LANG 变量不生成中文 locale,仍乱码。
- 只改时区变量不挂载 /etc/localtime,个别程序仍读系统时区。
- 中文字体缺失导致图片、报表里中文方框,这是字体问题不是 locale。
- Java 程序还需要 JVM 时区参数,光设 TZ 不够。
- 改 Dockerfile 后没重新 build,只 run 新容器旧镜像不变。
- Alpine 镜像用 apk 装 tzdata 和 locale,包名与 Debian 不同。
- 多容器集群时间应统一用 UTC 还是东八区,需全栈约定,避免日志错乱。
总结
乱码靠 LANG=zh_CN.UTF-8 和 locale-gen,时区靠 TZ=Asia/Shanghai 加挂载 /etc/localtime。三种方式里运行时变量最快,Dockerfile 固化最规范。Java、数据库等特殊程序还要单独配置,改完重建容器再用 date 和 locale 双重验证。
遇到问题加QQ23979811 协助处理