2018-01-15 更新
解决 : Java FontConfiguration Exception(安装 ttf-dejavu)
8u111-jdk-alpine在java开发中的NullPointerException错误解决方案
2018-01-12 更新
openjdk:8-jdk
镜像与 openjdk:8-jdk-alpine
镜像相比,体积大很多,而且应用的构建流程 (包含 push docker image) 非常慢,所以决定重新使用 openjdk:8-jdk-alpine
这个镜像.
在运行容器时, 使用 -v /etc/localtime:/etc/localtime:ro
参数看似可以解决时区问题.
$ docker run --rm -it -v /etc/localtime:/etc/localtime:ro openjdk:8-jdk-alpine /bin/sh
date
## ==> Fri Jan 12 11:20:18 CST 2018
但是当运行 Java 程序打印 new Date()
时依然存在时区问题, 所以通过挂载 /etc/localtime
的方法不奏效.
最终解决方法是:在 openjdk:8u151-jdk-alpine
镜像的基础上对时区进行调整,创建自定义镜像(https://hub.docker.com/r/donotlb/openjdk-alpine/)。
--------------------------原文------------------------------
最近发布了一个 Java 应用, 运行在 openjdk:8-jdk-alpine 镜像的容器中, 发现了一个时间问题.
问题描述
- 将 java.util.Date 类型的值存储到 MySQL 的 datetime 字段中, 日期的值在页面中显示时没有任何问题
- 去 MySQL (mysql:5.7.19) 中查看存储的值, 发现比显示的值晚 8 个小时
各环境下时区设置
1. host (宿主机 / centos7)
# date
Sun Nov 26 10:55:27 CST 2017
# timedatectl
Local time: Sun 2017-11-26 10:59:36 CST
Universal time: Sun 2017-11-26 02:59:36 UTC
RTC time: Sun 2017-11-26 02:59:34
Time zone: Asia/Shanghai (CST, +0800)
...
即, UTC 时间, 东 8 区
2. openjdk:8-jdk-alpine (docker image)
# date
Sun Nov 26 02:54:12 UTC 2017
即: UTC 时间, 零时区
3. mysql:5.7.19 (docker image)
# date
Sun Nov 26 03:23:05 UTC 2017
即: UTC 时间, 零时区
探索
apline 更改时区
apk add -U tzdata
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
缺点: 需要下载、安装 tzdata, 对于我所使用的 openjdk:8-jdk-alpine 镜像来说, 我有两个选择:
- 将时区设置的代码放到 Dockerfile, 在每次构建镜像时都设置一下时区 (不推荐)
- 基于 openjdk:8-jdk-alpine, 自己维护一个设置过时区的镜像
相比直接使用现成的镜像, 上面两个选择都稍显麻烦, 所以最后我的选择是, 用 openjdk:8-jdk 替代 openjdk:8-jdk-alpine, 只需要在运行容器时附加 -e TZ='Asia/Shanghai'
参数即可 (或者在 Dockerfile 中设置 TZ 环境变量). 缺点是 openjdk:8-jdk 尺寸略大.
总结(解决方法)
- 使用 openjdk:8-jdk 替代 openjdk:8-jdk-alpine, 并在 Dockerfile 中设置 TZ 环境变量.
... ENV TZ='Asia/Shanghai' ...
- 运行 mysql:5.7.19 镜像容器时, 附加
-e TZ='Asia/Shanghai'
参数