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.