skip to Main Content

I run docker compose to dockerize my Spring Boot app and MySQL database. The dockerization process return successful state but when I run my Spring Boot image, it always return this error:

Caused by: org.springframework.beans.BeanInstantiationException:
Failed to instantiate
[com.google.api.client.googleapis.auth.oauth2.GoogleCredential]:
Factory method ‘googleCredential’ threw exception with message:
src/main/resources/keys/uploadfiles.p12 (No such file or directory)

Although my project run smoothly on on my host system, it keep throwing that error on docker container.

Here is my dockerfile:

FROM maven:3.8.3-openjdk-17 as BUILD
WORKDIR /app
COPY . .
RUN mvn install:install-file -Dfile=jdf.jar -DgroupId=cue.lang -DartifactId=word-iterator -Dversion=1.0.0 -Dpackaging=jar
RUN mvn install:install-file -Dfile=VnCoreNLP-1.2.jar -DgroupId=vn.pipeline -DartifactId=vncorenlp -Dversion=1.2.0 -Dpackaging=jar
RUN mvn -f /app/pom.xml -B -DskipTests clean package

FROM openjdk:17-jdk
WORKDIR /app
ARG JAR_FILE_NAME=digital-library-0.0.1-SNAPSHOT.jar
COPY --from=BUILD /app/target/${JAR_FILE_NAME} /app/app.jar
EXPOSE 8080
CMD ["java", "-jar", "/app/app.jar"]

Here is my .dockerignore:

# Ignore everything
*

# Except the following files and folders
!.dockerignore
!jdf.jar
!pom.xml
!VnCoreNLP-1.2.jar
!models/
!src/

Here is my Spring Boot app config:

1st way:

    @Bean
    public GoogleCredential googleCredential() throws GeneralSecurityException, IOException {
        .......................
        return new GoogleCredential.Builder()
                ......................
                .setServiceAccountPrivateKeyFromP12File(new File("src/main/resources/keys/uploadfiles.p12"))
                .build();
    }

2nd ways:

public GoogleCredential googleCredential() throws GeneralSecurityException, IOException, URISyntaxException {
        .................
        File p12File = Paths.get(getClass().getClassLoader().getResource("keys/uploadfiles.p12").toURI()).toFile();
        return new GoogleCredential.Builder()
                ...............
                .setServiceAccountPrivateKeyFromP12File(p12File)
                .build();
    }

The file is in right folder and correctly refered so I don’t know how to solve this.

2

Answers


  1. I’d say, baking a private key into a Docker image is questionable due to security reasons. I would suggest keeping the private key file outside of the image as well as outside of your source code.

    You can create an environment variable, say GOOGLE_KEY_LOCATION, and point it to some place in the file system (not in the project’s src).

    Build the image without the key file. When creating a container, mount a volume for the key file, e.g., -v /local/file/system/uploadfiles.p12:/app/uploadfiles.p12:ro, and set the environment variable to the specified path in the container file system with -e GOOGLE_KEY_LOCATION=/app/uploadfiles.p12.

    In your Java code, use System.getenv("GOOGLE_KEY_LOCATION") instead of a hardcoded file path.

    This approach might seem cumbersome, but it lets you keep your source code and docker image free of security-sensitive information and is flexible enough to replace key file without code or image modification.

    Login or Signup to reply.
  2. It could also be that your container is running in a different environment than your host system, and the file paths are not absolute.

    Modify your Dockerfile with:

    COPY src/main/resources/keys/uploadfiles.p12 /app/src/main/resources/keys/uploadfiles.p12
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search