Search code examples
dockerhttpskeytool

Dockerfile keytool: getting "Certificate alias <name> already exists" even using "keytool - delete"


I use Dockerfile to create an image for our web app which requires HTTPS. However, I am getting Certificate not imported, alias <my-cert-name> already exists Java exception. When I tried without using Dockerfile, just from command line, I was able to delete the existing alias and export, import worked. But not with Dockerfile. Any ideas? Thanks!

Dockerfile:

  FROM openjdk:8-alpine

  #Starting https and certs configuration
  #Make directory for certs inside the container
  RUN mkdir -p usr/app/ssl/certs/

  #Copy certs from local to the container
  COPY myWebApp/src/main/resources/PT/certificates/my-cert-name.jks usr/app/ssl/certs/
  COPY myWebApp/src/main/resources/PT/certificates/trustStore.jks usr/app/ssl/certs/

  #Export/Import certificate 
  RUN cd usr/app/ssl/certs/ && \
      keytool -delete -alias my-cert-name -keystore my-cert-name.jks -storepass password123! && \
      keytool -export -alias my-cert-name -keystore my-cert-name.jks -file my-cert-name.crt -storepass password123! && \
      keytool -importcert -keystore trustStore.jks -alias my-cert-name -storepass password123! -file my-cert-name.crt -noprompt
  #Ending https and certs configuration

  RUN mkdir -p /usr/app/myweb

  COPY myWebApp/target/myWeb.war /usr/app/myweb

  CMD java -Xms512M -Xmx6144M -XX:MaxMetaspaceSize=3072M -jar /usr/app/myweb/myWeb.war
  EXPOSE 8080

Docker build command

  >docker build -it test-https-image .

Env:

 Using Docker desktop on windows 10. 

Thanks in advance!


Solution

  • I prefer the notation:

    RUN cd usr/app/ssl/certs/ && \
        keytool -delete -alias my-cert-name -keystore my-cert-name.jks -storepass password123! && \
        keytool -export -alias my-cert-name -keystore my-cert-namet.jks \
          -file my-cert-name.crt -storepass password123! && \
        keytool -importcert -keystore trustStore.jks -alias my-cert-name -storepass password123! \
          -file my-cert-name.crt -noprompt
    

    It is easier to double-check you are importing the same name you have deleted.
    (since -delete is a good way to force update an existing certificate)

    But the gist is:

    • you delete in my-cert-name.jks, while you import in trustStore.jks.
    • if the import fails, that means trustStore.jks already has a certificate for that name

    If that certificate was already in the copied keystore, I would not export/re-import it. (I only imported it in my previous answer)

    Make sure the "usr/app/ssl/certs" is the right path: I would rather use an absolute path, rather than a relative path.

    The OP fongfong confirms in the comments:

    I should delete the existing alias from trustStore.jks, not my-cert-name.jks