dockerkeytoolcacerts

Docker RUN with keytool import to Java truststore successful but fails at the same time during image build?


I have to add a custom root certificate to the Java trust store inside a docker environment. So I added the following command to my dockerfile:

RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt

I get the following output when building the docker image:

Step 10/10 : RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
 ---> Running in cbc2a547797e
Certificate was added to keystore
keytool error: java.io.FileNotFoundException: /opt/java/openjdk/jre/lib/security/cacerts (No such file or directory)
The command '/bin/sh -c $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt' returned a non-zero code: 1

I'm baffled by the following facts:

What I've checked:

Now I don't have any more ideas how to track this issue down.


Solution

  • Turned out that the problem was my fault™️

    There were a few things that had confused me:

    1. keytool displays Certificate was added to keystore even though that had actually failed – stupid
    2. I checked if the command works in the docker container, but I missed that I was testing in another version of the image that had Java installed in a different way
    3. The Java keystore is not always located in the same path – it may be $JAVA_PATH/lib/security/cacerts or it may be $JAVA_PATH/jre/lib/security/cacerts – obviously depending on whether a JRE or JDK is installed

    So my solution was to write a bash script:

    1. Is Java version 9 or better? Then import using -cacerts option which will automatically take care of the keystore location
    2. Else: does the $JAVA_HOME/jre directory exist? Then use -keystore $JAVA_PATH/jre/lib/security/cacerts
    3. Else: use -keystore $JAVA_PATH/lib/security/cacerts