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!
There are a couple of problems with what you're trying to do.
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
.
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.