Search code examples
javaspring-bootdockerkubernetesjib

Spring boot external config in a docker environment: application.yml does not exist


Before start explaining my issue, it's worth mentioning that although I am trying to work how to use Maven Jib plugin in conjunction with Spring Boot and Kubernetes, the issue is the same even if I try to use a normal docker.

I have used Kubernetes configMap to create the application.yml file and mount it as an external file to the Pod (/config/application.yml). The issue I have been facing is my application does not able to find the application.yml file and throw a typical exception:

ERROR [main] org.springframework.boot.SpringApplication: Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.example.Application]; nested exception is java.io.FileNotFoundException: class path resource [application.yml] cannot be opened because it does not exist

I have tried different approaches with Jib by using different arguments such as below.

  <container>
    <extraClasspath>/config/*</extraClasspath>
    <args>
      <arg>--spring.config.location=file:/config/application.yml</arg>
    </args>
    <jvmFlags>
      <jvmFlag>-Dspring.config.location=classpath:/,classpath:/config/,file:./,file:./config/,file:/config/</jvmFlag>
    </jvmFlags>
  </container>

None of them has worked for me. I have also tried to use the SPRING_CONFIG_NAME environment variable and set it to file:/config/application.yml for the pod, but still the same issue.

I can verify that the config file exists in the specified location and there are no permission issues (as far as I can tell).

Interestingly, when I create just an empty application.yml file in the default classpath (src/main/resources) then it passes the first verification and the application loads successfully (with using the actual values from /config/application), so whatever the issue is it is being impacted by an initial verification of Spring Boot before even passing the application file to the corresponding classes.


Solution

  • It turns out that the only item I need to have is the following:

    <container>
        <extraClasspath>/config</extraClasspath> <!-- No need to have * at the end -->
    </container>