'How to add extra linux dependencies into a spring-boot buildpack image?
I updated my spring-boot application to use buildpacks to create my docker-image instead of a dockerfile. I also use Apache POI in my application and since that update I get an error when generating an xlsx file. After some digging, I think it happens because the fontconfig and/or ttf-dejavu packages are missing. But how do I add these in the dockerimage? With a dockerfile I would just add something like
RUN apt-get update && apt-get install fontconfig ttf-dejavu
But how do I achieve the same with buildpacks?
Solution 1:[1]
As Michal outlined, using the bigger paketobuildpacks/builder:full builder isn't ideal. Also creating a custom builder & stack would be a huge overhead - since we want to use Cloud Native Buildpacks to free us from the burden of maintaining our own Dockerfile. And creating our own builder/stack would bring in way more complexity then we had before writing the Dockerfile.
On the other hand, the need to install separate packages into the container images created by the spring-boot-maven-plugin or Spring Boot Gradle plugins is widespread. So I thought of a minimally invasive solution - and here it is (as derived from). Let's assume our mvn spring-boot:build-image (or Gradle buildImage) command produced a container image called my-app:0.0.1-SNAPSHOT:
Now first install fontconfig ttf-dejavu into the image with (we need root priviledges for that):
docker run --user="root" --entrypoint launcher my-app:0.0.1-SNAPSHOT "apt-get update && apt-get install fontconfig ttf-dejavu -y"
Crab container id of the stopped container with docker ps -a:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ff7db32825f my-app:0.0.1-SNAPSHOT "launcher 'apt-get u…" 44 minutes ago Exited (0) 44 minutes ago reverent_swanson
Create a new container image based on the one we installed curl into with:
docker commit 2ff7db32825f my-app-with-fontconfig-ttf
Fire up a new container defining the correct ENTRYPOINT to start Spring Boot app & switching back to the CNB's standard cnb user (and not using root anymore to avoid potential security risks):
docker run --rm -p 8080:8080 --user="cnb" --entrypoint /cnb/process/web my-app-with-fontconfig-ttf
For a more detailled background info see this so answer also.
Solution 2:[2]
I will improve answer from jonashackt a little bit.
Instead of running docker run you can create new Dockerfile that will use image produced by Spring Boot plugin as a base image.
For example:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>acme.com/artifact:boot</name>
</image>
</configuration>
</plugin>
Then in your Dockerfile
FROM acme.com/artifact:boot
USER root
RUN apt-get update && apt-get install -y fontconfig ttf-dejavu
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jonashackt |
| Solution 2 | bsmk |
