spring-bootdocker-composepaketo

No Docker Compose file found in directory '/workspace/.'


I am using paketo buildpack for creating a docker image of my spring boot application using the below command:

gradlew bootBuildImage

It has successfully build the image with below message:

Successfully built image 'docker.io/library/employee-service:0.0.1-SNAPSHOT'

Inside my spring boot application I have a docker compose file named compose.yaml in the root to spin a mysql container. The contents of the file is given as below:

services:
  mysqldb:
    image: "mysql:latest"
    restart: always
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: employeeservice
      MYSQL_ROOT_PASSWORD: 1234

I am also using spring boot docker compose support in my project to fetch the mysql connection properties from the compose file.

implementation 'org.springframework.boot:spring-boot-docker-compose'

But when I run the image using the below command

docker run -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=int" docker.io/library/employee-service:0.0.1-SNAPSHOT

It is giving the below error:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

2024-12-20T15:13:21.369Z  INFO 1 --- [           main] o.p.employee.EmployeeServiceApplication  : Starting EmployeeServiceApplication v0.0.1-SNAPSHOT using Java 21.0.5 with PID 1 (/workspace/BOOT-INF/classes started by cnb in /workspace)
2024-12-20T15:13:21.371Z  INFO 1 --- [           main] o.p.employee.EmployeeServiceApplication  : The following 1 profile is active: "int"
2024-12-20T15:13:21.624Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: No Docker Compose file found in directory '/workspace/.'
        at org.springframework.util.Assert.state(Assert.java:97) ~[spring-core-6.1.8.jar:6.1.8]
        at org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager.getComposeFile(DockerComposeLifecycleManager.java:149) ~[spring-boot-docker-compose-3.3.0.jar:3.3.0]
        at org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager.start(DockerComposeLifecycleManager.java:109) ~[spring-boot-docker-compose-3.3.0.jar:3.3.0]
        at org.springframework.boot.docker.compose.lifecycle.DockerComposeListener.onApplicationEvent(DockerComposeListener.java:53) ~[spring-boot-docker-compose-3.3.0.jar:3.3.0]
        at org.springframework.boot.docker.compose.lifecycle.DockerComposeListener.onApplicationEvent(DockerComposeListener.java:35) ~[spring-boot-docker-compose-3.3.0.jar:3.3.0]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.8.jar:6.1.8]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.8.jar:6.1.8]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.8.jar:6.1.8]
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138) ~[spring-context-6.1.8.jar:6.1.8]
        at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.context.event.EventPublishingRunListener.contextLoaded(EventPublishingRunListener.java:98) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplicationRunListeners.lambda$contextLoaded$4(SpringApplicationRunListeners.java:72) ~[spring-boot-3.3.0.jar:3.3.0]
        at java.base/java.lang.Iterable.forEach(Unknown Source) ~[na:na]
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplicationRunListeners.contextLoaded(SpringApplicationRunListeners.java:72) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:433) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.0.jar:3.3.0]
        at org.purbarun.employee.EmployeeServiceApplication.main(EmployeeServiceApplication.java:12) ~[classes/:0.0.1-SNAPSHOT]
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91) ~[workspace/:na]
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53) ~[workspace/:na]
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58) ~[workspace/:na]

I am using Docker Desktop 4.37.1 and also note that I don't have any Dockerfile to create the image. I am using paketo buildpack to create the image.

I looked into similar threads given in https://stackoverflow.com/questions/77006121/no-docker-compose-file-found-in-directory but I am not convinced with the answers given sine I am using spring boot docker compose support.

Can anyone elaborate me why I am facing this issue and what's the way around.

Thanks in advance!


Solution

  • There are a couple of problems with what you're trying to do.

    1. The first is Spring Boot & buildpacks related. When you package your application into a container, your build system runs and produces a JAR/WAR. Then Spring Boot's tools take that and passes it to buildpacks to run and generate a container from the JAR/WAR.

      This means that ONLY the contents of your JAR/WAR will end up in the container (under /workspace) and files will exist in the same path structure as in your JAR/WAR in the container under /workspace.

      tl;dr if you want something in the container, you need to make sure that it's in your JAR file.

      You can run jar tf <file.jar> to check what is inside the JAR/WAR produced by a local build without buildpacks. That is what will end up in your container and it will end up at the same location as in that file, just under /workspace.

    2. You are running your application in a container. From inside the container, your application cannot talk to the Docker host and have it initiate other containers (at least by default). That is a basic security limitation and it's there to protect you.

      What you would typically do, and I would recommend, is make a second Docker compose file for production. In that, define a service for your app using the image you generated and any additional services that the app requires, like a database. You can then docker compose up and run your app and all its services.

      I suggest keeping the production & development compose files separately. That's a personal preference/organization thing. You don't necessarily have to, you could use a profile in the compose file to use the same file but only have the app start when a profile is enabled. It's really your choice on how you want to structure things.