Docker-alpine镜像导致的问题

前段时间接到一个需求,将现有的一个项目容器化部署。经过一段时间的折腾,总算成功的跑起来了。但是最近发现一个问题:图形验证码没法显示了。

通过查找日志发现以下异常堆栈:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
java.lang.NullPointerException: null
at sun.awt.X11FontManager.getDefaultPlatformFont(X11FontManager.java:779)
at sun.font.SunFontManager$2.run(SunFontManager.java:433)
at java.security.AccessController.doPrivileged(Native Method)
at sun.font.SunFontManager.<init>(SunFontManager.java:376)
at sun.awt.X11FontManager.<init>(X11FontManager.java:32)
at sun.reflect.GeneratedConstructorAccessor62.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:383)
at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
at java.security.AccessController.doPrivileged(Native Method)
at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
at java.awt.Font.getFont2D(Font.java:490)
at java.awt.Font.access$000(Font.java:224)
at java.awt.Font$FontAccessImpl.getFont2D(Font.java:228)
at sun.font.FontUtilities.getFont2D(FontUtilities.java:180)
at sun.java2d.SunGraphics2D.checkFontInfo(SunGraphics2D.java:645)
at sun.java2d.SunGraphics2D.getFontInfo(SunGraphics2D.java:806)
at sun.java2d.pipe.GlyphListPipe.drawString(GlyphListPipe.java:50)
at sun.java2d.SunGraphics2D.drawString(SunGraphics2D.java:2887)
...

结合源码发现,应该是无法获取到字体导致的异常:

1
graphics.setFont(new Font("Default", Font.PLAIN, fsize));

由于代码没有做出过变更,所以毫无疑问,应该是环境的问题了。

于是我进入Dokcer容器查看相关字体:

1
2
docker exec -it containerId bash
fc-list

发现无任何内容输出。经过一番查找,解决办法如下:

  1. 进入容器安装字体(只能临时解决,当重新构建后,字体会丢失)

    1
    apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/*
  2. 修改Dockerfile 在构建镜像时安装字体(会影响构建速度,安装字体比较慢)

    1
    RUN apk add --update ttf-dejavu fontconfig && rm -rf /var/cache/apk/*
  3. 更改基础镜像(推荐)

    我这边出问题的容器是基于tomcat:8.0-jre7-alpine构建的,alpine tag的镜像比较小,比较干净。

    我到docker hub上找到了类似的镜像,slim tag的。

    修改Dockerfile,将FROM tomcat:8.0-jre7-alpine 改为 FROM tomcat:8.0-jre7-slim即可。

作者

太阳当空赵先生

发布于

2019-09-26

更新于

2022-02-22

许可协议

评论