最近碰到一個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可以解決這種問題。