Create a containerized Spring Boot application using Docker
Clone and run a Spring Boot application with Maven
Create a new Dockerfile which contains instructions required to build a Java image
Run the newly built image as a container
Set up a local development environment to connect a database to the container
Use Docker Compose to run the Spring Boot application
Configure a CI/CD pipeline for your application using GitHub Actions
Deploy your application to the cloud
To complete this tutorial, you need the following:
Docker running locally.
A Git client
text editor to edit files.
Clone and run a Spring Boot application with Maven:-
Let’s clone the sample application that we'll be using in this module to our local development machine
cd /java_projects
git clone https://gitlab.com/javax2/user-service.git
cd user-service
mvnw spring-boot:run
To test that the application is working properly, open a new browser and navigate to
http://localhost:8080/users/abc
Press CTRL-c from within the terminal session where the server is running to stop it.
Create a new Dockerfile which contains instructions required to build a Java image
# syntax=docker/dockerfile:1
FROM eclipse-temurin:17-jdk-jammy
WORKDIR /app
COPY .mvn/ .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:resolve
COPY src ./src
CMD ["./mvnw", "spring-boot:run"]
New Docker file
# syntax=docker/dockerfile:1
FROM maven:3.8.3-openjdk-17
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN mvn package
#ENV PORT 5000
#EXPOSE $PORT
CMD [ "sh", "-c", "mvn -Dserver.port=${PORT} spring-boot:run" ]
Create a .dockerignore file (Optional)
To increase the performance of the build, and as a general best practice, we recommend that you create a .dockerignore file in the same directory as the Dockerfile. For this tutorial, your .dockerignore file should contain just one line:
target
Let’s build our first Docker image.
$ docker build --tag javaxin/user-service .
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
javaxin/user-service latest b1b5f29f74f0 47 minutes ago 401MB
An image name is made up of slash-separated name components. Name components may contain lowercase letters, digits, and separators. A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator.
To create a new tag for the image we’ve built above, run the following command:
$ docker tag javaxin/user-service:latest javaxin/user-service:v1.0.0
Now, run the docker images command to see a list of our local images.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
javaxin/user-service latest bfd2fd59ae96 14 minutes ago 407MB
javaxin/user-service v1.0.0 bfd2fd59ae96 14 minutes ago 407MB
Let’s remove the tag that we just created. To do this, we’ll use the rmi command. The rmi command stands for “remove image”.
$ docker rmi javaxin/user-service:v1.0.0
Untagged: javaxin/user-service:v1.0.0
Note that the response from Docker tells us that the image has not been removed but only “untagged”. You can check this by running the docker images command.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
javaxin/user-service latest bfd2fd59ae96 47 minutes ago 407MB
Our image that was tagged with :v1.0.0 has been removed, but we still have the javaxin/user-service:latest tag available on our machine.
Run the newly built image as a container
To run an image inside a container, we use the docker run command. The docker run command requires one parameter which is the name of the image.
$ docker run javaxin/user-service
Let’s open a new terminal then make a GET request to the server using the curl command.
$ curl --request GET \
--url http://localhost:8080/actuator/health \
--header 'content-type: application/json'
curl: (7) Failed to connect to localhost port 8080: Connection refused
As you can see, our curl command failed because the connection to our server was refused. It means that we were not able to connect to the localhost on port 8080.
$ docker run --publish 8080:8080 javaxin/user-service
Now, let’s rerun the curl command from above.
$ curl --request GET \
--url http://localhost:8080/actuator/health \
--header 'content-type: application/json'
{"status":"UP"}
Success! We were able to connect to the application running inside of our container on port 8080.
Now, press ctrl-c to stop the container.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ff83001608c javaxin/user-service "./mvnw spring-boot:â¦" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp trusting_beaver
Docker can run your container in detached mode or in the background. To do this, we can use the --detach or -d for short. Docker starts your container as earlier, but this time, it will “detach” from the container and return you to the terminal prompt.
$ docker run -d -p 8080:8080 javaxin/user-service
Docker started our container in the background and printed the Container ID on the terminal.
To name a container, we just need to pass the --name flag to the docker run command.
$ docker run --rm -d -p 8080:8080 --name springboot-server javaxin/user-service
We need to pass the name of the container or we can use the container ID.
$ docker stop trusting_beaver
Docker Restart
$ docker restart trusting_beaver
To name a container, we just need to pass the --name flag to the docker run command.