Reputation: 33
When I create a docker image with a spring boot app, I see encoding problems in filenames of directories mounted into the running container with the spring boot app. I create the docker image by the gradle task bootBuildImage
as described here.
When I look into the running container, I see the locale is set to posix. In a regular Dockerfile I would run the appropriate commands to setup a german utf-8 locale setting. But spring boot is using cloud foundry buildpacks and I can find no place to hook into for the locale setting. How can I adjust the locale for the image in the build process?
cnb@9d24bfe67b9e:/$ locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
Upvotes: 3
Views: 1309
Reputation: 387
To tailor the environment variables for the compiled image, consider employing the Environment Variables buildpack, as elaborated here. When working with a Gradle build script, adjust the bootBuildImage
task as follows:
tasks.named<BootBuildImage>("bootBuildImage") {
// ...
environment["BPE_LANG"] = "de_DE.UTF-8"
/// ...
}
It's unnecessary to set LC_*
variables explicitly since they are automatically inferred from LANG
upon container initiation:
cnb@1a31e0852193:/$ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=de_DE.UTF-8
LANGUAGE=
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=
The warnings are a result of the specified locale not being pre-generated in the container. While altering the run image, as suggested by Scott, is a solution, it does entail additional maintenance. However, for a JVM-based application, these warnings might be negligible since the JVM utilizes $LANG
only to set the default locale.
In my opinion, a cleaner solution for a JVM application within a container built by bootBuildImage
is to use C.UTF-8
, so you get the desired UTF-8 character encoding without any warnings about non-present locales in the system logs. The locale used by the Java application can in turn be configured via the corresponding JVM system properties (user.language
, user.country
and user.variant
). In the Paketo base images, which are used by default by the Spring Boot Gradle Plugin, C.UTF-8
is preinstalled:
cnb@d94c8fe708ff:/# locale -a
C
C.utf8
POSIX
en_US.utf8
Therefore, this is the bootBuildImage
task configuration I would use:
tasks.named<BootBuildImage>("bootBuildImage") {
// ...
environment["BPE_APPEND_JAVA_TOOL_OPTIONS"] = "-Duser.language=de -Duser.country=DE"
environment["BPE_DELIM_JAVA_TOOL_OPTIONS"] = " "
environment["BPE_LANG"] = "C.UTF-8"
/// ...
}
Upvotes: 0
Reputation: 729
Even though I think Scotts answer ist still the best, as an alternative option you can set enviromentvariables for the builder image, which can control the environment variables for the final image.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<env>
<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:+HeapDumpOnOutOfMemoryError</BPE_APPEND_JAVA_TOOL_OPTIONS>
</env>
</image>
</configuration>
</plugin>
Upvotes: 0
Reputation: 5145
By default, the Spring Boot Gradle plugin uses the Paketo builder image and run image. The run image provides the base OS layer for the generated app image, and this is where the locale is coming from.
One way to override the locale would be to generate a custom run image based on the Paketo run image and setup the locale in your custom run image. A Dockerfile for the custom run image might look something like this:
FROM paketobuildpacks/run:base-cnb
USER root
RUN apt-get install -y locales
RUN locale-gen de_DE.utf8
ENV LANG de_DE.UTF-8
ENV LANGUAGE de_DE:de
ENV LC_ALL de_DE.UTF-8
Once you've built and tagged the custom run image, you can override the default run image in the Spring Boot Gradle plugin configuration with the runImage
property or on the command line with the ---runImage
flag.
Upvotes: 2