Containerize a very simple Spring Boot application using Docker

Containerize a very simple Spring Boot application using Docker

We are in the microservice era, we need to deploy our applications very fast. Before containers, Kubernetes etc. deploying a Java or Spring boot project was a painful process. Today I’m going to containerize a very simple Spring boot application using docker.

Key project details

  • Java version: 17

  • Spring boot version: 3.3.4

  • Build tool: Maven

  • Dev Java Distro: Azul Zulu 17.0.13

We can skip other details as those aren’t scope in this article, but definitely you can check out the codebase.

The codebase of Spring boot

A simple rest API endpoint for testing only.

@RestController
@RequestMapping("/")
public class GreetingController {

    @GetMapping
    public String greetMessage() {
        return "Welcome to the docker world";
    }
}

Build package

As this is a maven project. we can clean and build the project and generate the bundle, here it is jar.

If you’ve maven globally then

mvn clean install

If not then

./mvnw clean install

Or the easy way using the Intellij Idea,

Just click the clean first and then install.

The clean command delete the existing target folder in the root project directory. and then install generates the new one.

Now the question is how this naming convention comes from for the jar. Check in the project’s pom.xml file, you can see the artifactId and version. The jar naming is the combination of those.

    <artifactId>docker-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

I’ve modified those to simple ones. The artifactId is app and the version is 1. Again execute maven clean and install commands so it can generate a new package using new names. So, the final name is app-1.jar.

The Dockerfile

Now, it time for dockerizing. First we need the Dockerfile where we specify the container environment, copy our jar to the container and specify the run command.

First create the Dockerfile in the project root directory. The naming is case-sensitive.

  • First specify the base image, here we need a java image which is using a small Linux distro. The alpine is one who provides minimal Linux setup. Also I’m using Azul-Zulu variant and OpenJDK 17, so, I want to specify the same in container environment too.

  • Next we need to specify that we need to copy the jar file (here it is app-1.jar which generates in the target folder after maven install) to the container.

  • Lastly specify the run the jar command

Let’s translate those in our Dockerfile.

FROM azul/zulu-openjdk-alpine:17-latest
WORKDIR /simple-app
COPY target/app-1.jar app.jar
ENTRYPOINT ["java","-jar","/simple-app/app.jar"]

Optionally, we can define the working directory.

Build the image

Now, build the image using this command.

docker build -t demoapp .

here this demoapp is the docker image name, you can specify anything meaningful with version. Don’t forget to mention the (.) as it refers the current working directory.

Once finished, check the image.

docker images

You can see something like this

REPOSITORY                    TAG       IMAGE ID       CREATED              SIZE
demoapp                       latest    b10733b77761   About a minute ago   487MB

Although we’ve used alpine version, it is still 487MB 😂.

Run the image

Now run the image using this command. I’ve specified port using the -p arg.

 docker run -p 8080:8080 demoapp

we can see the container is running. Now check the application.

curl http://localhost:8080/

Also, check the containers using this command

docker container ls

We can see a output like this

CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS
 PORTS                    NAMES
dd4dd1cc8676   demoapp   "java -jar /simple-a…"   2 minutes ago   Up 2 minutes
 0.0.0.0:8080->8080/tcp   kind_meninsky

Performance

If you’ve one big monolith project, then there is scope of improvement. The idea is not putting a big fat jar, instead copy build classes/dependencies. I don’t put this material in this article.

Create tag

Before pushing to the container registry, we need to create a tag from the local image. Let’s create one.

docker image tag demoapp leeonscoding/demoapp

Push to registry

For this article, I’m going to push in the public docker registry. First we need to login in terminal.

docker login -u leeonscoding

Here leeonscoding is my username, you should put yours. This command will asks for the password. Put your password or access token for a successful login. Now it’s time to push the image.

docker push leeonscoding/demoapp

Previously we’ve seen the image size was 487MB, so it will take time. After successful push you can see it in docker hub.

For this app, the URL is here.

Conclusion

The container orchestration tools like kubernetes used containers for deploying an application. In this article, I’ve covered how to containerize a simple spring boot application docker. The full code is here. I hope now you can containerize any simple spring boot application.