I am trying to setup my development environment using docker for a sprint boot application.
I am using intellij idea.
Here is the dockerfile.
FROM gradle:7.4.2-jdk18-alpine AS build
COPY --chown=gradle:gradle ./ /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon --debug
FROM openjdk:19-slim
EXPOSE 5097
EXPOSE 5005
RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/*.jar /app/spring-boot-application.jar
ENTRYPOINT ["java", "-Xdebug", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005", "-jar", "/app/spring-boot-application.jar"]
and docker-compose.yml is:
version: '3.7'
services:
hmis-config-service:
build:
context: .
dockerfile: Dockerfile
image: 'hmis-config-service:0.0.0.1'
ports:
- "9060:5080"
- "8091:5005"
volumes:
- myapp:/home/gradle/src
environment:
db.url: 'jdbc:postgresql://host.docker.internal:5432/hms'
db.username: 'postgres'
db.password: 'pgsroot'
GRADLE_HOME: /usr/local/gradle
JAVA_HOME: /usr/lib/jvm/java
M2: /usr/local/apache-maven/bin
M2_HOME: /usr/local/apache-maven
volumes:
myapp:
Every time I try to build it, it takes a long time because it downloads all gradle dependencies. Hence even a small change takes a long time.
If project is started using
docker-compose up # without the --build flag
it starts instantaneously but the changes made aren't in the container.
I have tried to mount the volume /home/gradle/src to keep the dependencies synced but that didn't do anything.
What can be done to improve the build time and cache the dependencies?
CodePudding user response:
Is there a reason you need to build the app in the docker context? If you build it outside (locally), and only copy the artefacts, you can leverage build caching from the (local) gradle
daemon, which should increase the speeds significantly.
Essentially, you are building the project from scratch on each build/invocation.
i.e, don't build inside the Dockerfile
, only copy the already built artefacts.
PS: If you have to build inside the docker context (for instance, if you don't have a JDK locally), you can try to figure out where gradle
keeps its local cache and also sync/copy that over.
CodePudding user response:
As you mentioned the issue is the build takes long time because it downloads dependencies each time.
If that is the case, you can try using multi-stage builds.
Basically you download the dependencies once then you just copy them each time. This also reduces the size of the image.
References:
- https://docs.docker.com/develop/develop-images/multistage-build/
- https://spring.io/guides/topicals/spring-boot-docker/
- https://gist.github.com/msauza/6a906e879549e218c54868d81161afcb
- https://hashedin.com/blog/a-guide-to-optimize-build-time-in-docker/
P.S: I have not tried this for Spring Boot applications, but they work well for applications based on Go.