Home > Back-end >  How to create Dockerfile for Spring Boot app?
How to create Dockerfile for Spring Boot app?

Time:12-20

Hello Fellow Developers,

I am new to software development and looking forward to doing transitioning to software development.

I am learning new skills and tools to scale up and I came across DOCKER and KUBERNETES

I have completed my backend with spring boot, java and MYSQL I just wanted to know how to dockerize an image for the spring boot application in an industrial real-time manner just to get a hang of it.

Things to image

Environment: JAVA 17

Dependencies: POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.greatlearning.employeemanagementservice</groupId>
    <artifactId>employeemanagementservice</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>employeemanagementservice</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
        <!-- spring security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Application-properties:

server.port=8082
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/empdb
spring.datasource.username=root
spring.datasource.password=*s12
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.main.allow-bean-definition-overriding=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

This is an employee management project with simple CRUD operation I have done. It would be helpful if someone can guide me through Docker image settings.

Pardon me, If it is inappropriate to post such questions in a stack overflow.

CodePudding user response:

Try the follwoing Dockerfile. It performs a multi-stage build where in the first stage, your code is compiled to an executable. Then in the next stage, only the parts necessary for running your application are copied so that your Docker image has less size than if you copied all your uncompiled and compiled code in the Docker image. For more infomation about multi-stage builds, consult the official documentation or one of the countless internet tutorials.

FROM maven:3.8-openjdk-17 as maven
WORKDIR /app
COPY ./pom.xml .
RUN mvn dependency:go-offline
COPY ./src ./src
RUN mvn package -DskipTests=true
WORKDIR /app/target/dependency
RUN jar -xf ../employeemanagementservice.jar

FROM ibm-semeru-runtimes:open-17-jre-centos7
ARG DEPENDENCY=/app/target/dependency
COPY --from=maven ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=maven ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=maven ${DEPENDENCY}/BOOT-INF/classes /app
CMD java -server -Xmx1024m -Xss1024k -XX:MaxMetaspaceSize=135m -XX:CompressedClassSpaceSize=28m -XX:ReservedCodeCacheSize=13m -XX: IdleTuningGcOnIdle -Xtune:virtualized -cp app:app/lib/* com.greatlearning.employeemanagementservice.Application

I made the following assumptions:

  1. Your build artifact is named employeemanagementservice.jar. Check your target directory after your maven build to verify. I always configure it like this in the pom.xml
 <build>
        <finalName>${project.artifactId}</finalName>
 </build>
  1. You run your tests in a CI/CD pipeline and don't want to run them in the Docker image build step. If you wanted to run your tests you'd have to remove the -DskipTests=true from the RUN mvn package -DskipTests=true comannd.

  2. Your main class is called Application and it resides in the com.greatlearning.employeemanagementservice package. If not, change it in the Docker CMD command.

  3. You want your service to use at most 1GB of RAM. If not, change the -Xmx1024m to your desired amount. The other java arguments are for optimization purposes, you can look them up online.

  • Related