skip to Main Content

Context: I’m able to dockerize and run my Springboot app locally just fine with the below, following the most common recommendations of using a generated jar file to run the app via Docker.

Question: Since it’s bad practice to push the jar file to the repo as it’s going to potentially contain secrets from the local application.yml files, and the docker file depends on the jar file, how can I have my app be dockerized not just locally but on the cloud in anywhich cicd pipeline? Would my next step be modifying the dockerfile to copy over the project directory, and handle generating the jar file itself? Or should I not be using a jar at all and copying over the directory and using a CMD [Some Spring Run command)]

DockerFile:

FROM maven:3.8.5-openjdk-17
ADD target/xyz.jar xyz.jar

ENV RESTFUL_PORT 8080
ENV PORT_POSTGRES 5432
EXPOSE $RESTFUL_PORT
EXPOSE $PORT_POSTGRES

ENTRYPOINT ["java", "-jar","/xyz.jar"]

The pom.xml plugin which generates the jar file:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

Docker Steps

  1. Build the Jar:
    mvn clean install
  2. Build the Image:
    docker build -t xyz -f Dockerfile
  3. Run the Image:
    docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=dev" xyz

2

Answers


  1. Chosen as BEST ANSWER
    FROM maven:3.8-openjdk-17-slim AS build
    WORKDIR /workspace/app
    
    COPY mvnw .
    COPY .mvn .mvn
    COPY pom.xml .
    COPY src src
    
    RUN mvn -f /workspace/app/pom.xml install
    RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
    
    FROM openjdk:17-oracle
    VOLUME /tmp
    ARG DEPENDENCY=/workspace/app/target/dependency
    COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
    COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
    COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
    ENTRYPOINT ["java","-cp","app:app/lib/*","com.demo.DemoServiceApplication"]
    

    Got it working with this, only needing to change the last line.

    Docker Command:

    • docker build -t demo -f Dockerfile .
    • docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=develop" demo:latest

    This results in a DockerFile that is not dependent on an external jar file and can be run in isolation against a repo for a cicd pipeline.

    Source: Toptal - Multi-Stage Build


  2. The Dockerfile can be like this:

    # Build Stage
    FROM maven:3.8-openjdk-17-slim AS build
    COPY src /home/app/src
    COPY pom.xml /home/app
    RUN mvn -f /home/app/pom.xml clean package
    
    # Execution Stage
    FROM openjdk:17-oracle
    COPY --from=build /home/app/target/demo-0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
    EXPOSE 8080
    ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]
    

    To build docker image

    $ docker build -t demo-app:1.0 .   
    

    Run docker image

    $ docker run -p 8080:8080 demo-app:1.0
    

    Simple build part of pom.xml will work

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search