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 即成功。

常见坑

  1. 基础镜像没装 locales,只设 LANG 变量不生成中文 locale,仍乱码。
  2. 只改时区变量不挂载 /etc/localtime,个别程序仍读系统时区。
  3. 中文字体缺失导致图片、报表里中文方框,这是字体问题不是 locale。
  4. Java 程序还需要 JVM 时区参数,光设 TZ 不够。
  5. 改 Dockerfile 后没重新 build,只 run 新容器旧镜像不变。
  6. Alpine 镜像用 apk 装 tzdata 和 locale,包名与 Debian 不同。
  7. 多容器集群时间应统一用 UTC 还是东八区,需全栈约定,避免日志错乱。

总结

乱码靠 LANG=zh_CN.UTF-8 和 locale-gen,时区靠 TZ=Asia/Shanghai 加挂载 /etc/localtime。三种方式里运行时变量最快,Dockerfile 固化最规范。Java、数据库等特殊程序还要单独配置,改完重建容器再用 date 和 locale 双重验证。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-11-14 07:11 
'); })();