最近碰到一个docker编码问题,调查过程的比较艰辛,写篇博客记录下。
问题是这样的:某个项目发现乱码问题,Java代码显示的默认编码为acsii(System.out.println(Charset.defaultCharset().name()))。我们知道Java应用的默认编码依赖于Locale,于是登录到容器,运行locale命令,得到的结果是en_US.UTF8。 此时脑袋中就一堆的问号了。为什么Java获得的编码会和locale显示的不一致呢?这还是第一次碰到。
后面就和负责生成docker 镜像的同事一起调查。docker file 内容如下:
FROM artifactory.local/docker-virtual/centos/centos7.6/javaapp:stable USER root COPY ip.jar /opt/application/app.py COPY start.sh /opt/application/start.sh RUN chown -R app:app /opt/application && chmod -R 755 /opt/application RUN echo "export LANG=en_US.utf8" >> /etc/bashrc #ENV LANG en_US.UTF-8 USER app ENTRYPOINT ["/opt/application/start.sh"]
同时,我们做了以下尝试:
1. 启动一个容器 -> 进入到容器中执行Java命令:java -jar test.jar,这个应用会打印编码=UTF-8。
2. 通过生成docker image -> docker run <image>, 打印的编码为ascii。
3. 在docker file中新增ENV LANG en_US.UTF-8, 编码等于UTF-8。
结论:在docker file 中使用 export LANG=en_US.utf8这行命令实际是要登录之后才会起作用的,直接在docker file上并不起作用,这就是为什么第二种情况的编码为ascii,第一种情况是正常的。通过在docker file种添加ENV可以解决这种问题。