0% found this document useful (0 votes)
43 views19 pages

Vvvvvvvvvvvvvvvvvvvvvvvvvvvveffortless Containerization - Deploying Spring Boot and MySQL With Docker and Docker Compose - DEV Community

ddddddddddddssssssssssssssssssssssss

Uploaded by

ranjan patali
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views19 pages

Vvvvvvvvvvvvvvvvvvvvvvvvvvvveffortless Containerization - Deploying Spring Boot and MySQL With Docker and Docker Compose - DEV Community

ddddddddddddssssssssssssssssssssssss

Uploaded by

ranjan patali
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV

Compose - DEV Community

Rajdip Bhattacharya
Posted on Aug 17, 2023

4 1 1

Effortless Containerization: Deploying Spring


Boot and MySQL with Docker and Docker
Compose
#docker #springboot #devops #webdev

Greetings!

In the increasing complexity of software development, there is a general shift from


manual configuration to automation. Be it development, or deployment, seamless
development and integration is the word of the town.
Hence, in this blog, I plan to crack open a critical aspect of DevOps:
Containerization.

What is Containerization?
Before we dive into that, first let us understand the old school way of doing it. Make a
supposition that you are developing an application. You know every inch of this
application. Be it the databases or the environments, you have everything set up.
Now consider that this application is done with development. You now want to host it
someplace. For instance, let's say you decided to use Amazon EC2 for its ease of use.

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 1/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Now let's look at the steps that you would perform to get this application running (at
least).

Clone the application into the EC2 instance


Install required dependencies (Java, NodeJS, etc.)
Set up the required environmental variables
Test the application for bugs or errors.

While this might look trivial, it becomes a pain when you have to do it over and over
again, for all of your applications. There is always a chance that some OS feature
would break your application, some dependency won't be installed, some
environmental variable might not be configured. It becomes extremely difficult to
debug such applications. Here is where containerization comes to our rescue.

A container includes everything needed for an application to run: the code, runtime,
system libraries, and settings. This self-contained unit ensures that the application
behaves consistently regardless of the environment it's deployed in. Containers are
lightweight, portable, and can be easily moved between different host systems or
cloud platforms without significant modifications.

Key features and benefits of containerization include:

Isolation: Containers are isolated from each other and from the host system,
preventing conflicts between dependencies and runtime environments.

Consistency: Containers ensure that an application behaves the same way in every
environment, reducing the "it works on my machine" problem.

Portability: Containers can be moved between different systems or cloud platforms


with minimal effort, making application deployment and migration easier.

Resource Efficiency: Containers share the host OS kernel, resulting in lower


overhead compared to traditional virtualization.

Scalability: Containers can be rapidly scaled up or down to accommodate varying


workloads and demands.

Version Control: Container images can be versioned, allowing teams to track


changes and roll back to previous versions.

DevOps Enablement: Containers facilitate DevOps practices by enabling continuous


integration, continuous delivery, and automated deployment.
https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 2/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Roadmap

In this blog, we would be doing the following things.

Create a simple SpringBoot application to manage a Person entity


Set up MySQL using Docker
Create a Docker Image of our application
Develop a run-and-deploy of the entire infrastructure using Docker Compose

To follow along, clone this repository (also leave a star maybe?)

So, let's get started!

Creating the SpringBoot application


We would start with our SpringBoot application. Head over to Spring Initializr and
create a project using the following settings and dependencies.

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 3/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

To summarize, we are using:

1. Lombok: For annotation based POJOs.


2. Spring Web: For our web application.
3. Spring Data JPA: For Hibernate ORM
4. MySQL Driver: Enables our application to talk to a MySQL database.
5. Spring Boot Actuator: For health checks

Once you are satisfied, generate the project, extract it, and open it with your favourite
code editor.

We would be creating the following classes:

1. Person :Base entity for holding the person.


2. PersonPayload : Contains the request body for a Person object.
3. PersonDTO : Contains the DTO of the person object when the API returns data.
4. PersonService : Contains business interface for managing persons.
5. PersonServiceImpl : Contains the implementation of PersonService .
6. PersonController : Exposes the endpoints for managing Persons.
7. PersonRepository : Enables us to use JPA

Here are a list of endpoints we would be developing in PersonController :

POST /api/person/ : Creates a person


https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 4/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

PUT /api/person/{personId} :Updates a person with the given data


GET /api/person/all?page=<page_index>&size=<page_size> : Gets the list of all persons
on the database. page and size helps us to control the index of a page and
number of items in a page in pagination.
GET /api/person/{personId} : Gets a person by their ID
DELETE /api/person/{personId} : Delete a person by their ID

Our final folder structure should look something like this:

Since this blog is focussed on getting Docker set up, I would be skipping the code
explanation in here. You can always clone the repository and check the code.

Let's go through the application.properties file

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 5/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

As you can see, I have injected environmental variables. This would allow us to
resolve the values at runtime. It gives us the flexibility to configure our application
without actually touching any of the code. Any change that you would like to make
to the environments, all you need to do is tweak the values as per your wish in the
system's environment.

I will be using a .env file to feed the values into the application. Nearly every IDE has
the support for doing so. In case you can't figure out how to include a .env file into
your execution environment, you can try setting those values in the environment of
your OS. Alternatively, you can let that untouched, since all the keys have a default
value assigned to them.

.env.docker : Used when deployed using docker compose.

.env.local : Used when using just docker.

Now, we have our application ready. Before we are actually able to run it, we need to
launch MySQL, which we will do next.

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 6/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Launching MySQL using Docker


To begin with this step, first, make sure that you have docker installed. This article
provides an excellent guide in letting you set up docker. Once it is set up, we are
ready to move forward.

We will be launching a MySQL docker container using this command:

docker run --name springboot-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql

Here is a breakdown into what this command does:

It creates us a container from the mysql docker image


It assigns a name to that container using --name springboot-test
It exposes the standard mysql port of the docker container to the host's network
using --p 3306:3306
It sets the root password of the docker image to root using -e
MYSQL_ROOT_PASSWORD=root
Lastly, it tells the container to run in detached mode, meaning, it won't be
attached to the console where we are writing this command using the -d flag

With that, we have a brand new mysql container up and running which you can check
using:

docker ps

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 7/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

At this point of time, we are ready to launch our springboot application. Go to the
root of the project, and run

If you have maven installed:

mvn spring-boot:run

If you don't have maven:

mvnw spring-boot:run

You can verify that the application is running using:

curl http://localhost:8080/actuator/health

Now we are ready to finally dockerize the application!

Dockerizing the application


We use Dockerfile to containerize any application using docker. This article provides
all that you need to know to get started. For starters, I'll run down through the
docker image that I'm creating.

Go to the project's root


Create a file named Dockerfile
Paste the following content in the file

# The base image on which we would build our image


FROM openjdk:18-jdk-alpine

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 8/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

# Install curl and maven


RUN apk --no-cache add curl maven

# Set environment variables


ENV DB_HOST=${DB_HOST}
ENV DB_NAME=${DB_NAME}
ENV DB_USER=${DB_USER}
ENV DB_PASS=${DB_PASS}

# Expose port 8080


EXPOSE 8080

# Set the working directory


WORKDIR /app

# Copy the pom.xml file to the working directory


COPY pom.xml .

# Resolve the dependencies in the pom.xml file


RUN mvn dependency:resolve

# Copy the source code to the working directory


COPY src src

# Build the project


RUN mvn package -DskipTests

# Run the application


ENTRYPOINT ["java", "-jar", "target/application.jar"]

Notice that I'm still not hard coding the environmental variables. Also, note that, the
last line mentions using the command java -jar target/application.jar to launch the
container. For this to happen, we need to first set the build name to application in
the pom.xml .

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 9/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

To optimize the docker build process, I have first copied the pom.xml and then
resolved the dependencies before actually copying our soruce code. This is done with
the purpose of reducing the number of layers docker rebuild during its build process.
Source code is bound to change often. Putting that at the very top would mean all
the subsequent layers would be rebuilt.

Docker networking
Before we get started with running the application, let's first get a few points right
about networking in docker. When we run a docker image, the container boots up
into a separate docker network that works in isolation to our host network and other
docker containers. Hence, container A can't ping container B if they are running on
different networks. In our case, we would be running the springboot application and
MySQL database. So if we let them run in different networks, our containers won't be
able to intercommunicate.

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 10/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

There are two ways to address this issue:

1. Create a custom network and attaching our containers to that network.


2. Attaching the containers directly to the host network.

Using custom network

Let's start by creating a docker network

docker network create dummy-network

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 11/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Once done, you can verify this using

docker network ls

Now, we need to migrate our MySQL container to this network. We do this by:

docker network disconnect bridge springboot-test


docker network connect dummy-network springboot-test

Now, we can verify that these commands work by inspecting the Containers section
in the output of this command:

docker network inspect dummy network

Using host network


Recall that we used the flag -p 3306:3306 while creating our MySQL container. This
flag creates a channel in the network of our MySQL container that allows us to

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 12/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

communicate with the container's 3306 port via our hosts 3306 port.

We can bypass this by instructing docker to run the container directly on the host's
network. This can be done by:

docker run --name springboot-test --network host -e MYSQL_ROOT_PASSWORD=root -d mysq

Notice that I replaced the -p flag with the --network flag. When we are using the
host network driver, port mappings are neglected by docker.

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 13/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Now that we know the fixes, let's move towards making the application work.

Running the SpringBoot application


We have created our Dockerfile in the previous sections. Now, first, we need to create
a docker image out of that file. To do this, go to the root directory of the project and
run:

docker build -t application:latest .

Next, run

docker run --name temp --rm -p 8080:8080 --env-file .env.local --network dummy-netwo

This command will do the following:

--name temp will set the name of the container as temp


--rm will remove the container once it's stopped
-p 8080:8080 will map the container's port 8080 to the host's port 8080
--env-file .env.local will read the environments from the .env.local file
--network dummy-network will associate the container to dummy-network

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 14/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Lastly, it will launch the docker container

In case you get any error stating that the DB connection fail, I would like to point you
to the file. In there, we have a key called DB_HOST with the value set as
.env.local
springboot-test . This is the name we used when launching the MySQL docker
container. The above command will only work when these conditions are satisfied:

The MySQL container is named springboot-test


Both the database and the application are in the same network.

Alternatively, if you want to use some other name for the MySQL container, you can
should the name in the .env.local file aswell.

Now that we have everything up and running, we can verify our network again using
the docker network inspect dummy-network command.

Using docker compose


No doubt that most of you have felt that this is too much of configuration. Yes,
configuration comes as the cost of making applications reliable and secure. But don't
feel demotivated, docker compose is here to rescue!

docker compose is a plugin that reads deployment configurations from a file


(typically named docker-compose.yaml) and deploys the entire infrastructure at one
click!

For doing this, let us first create the docker-compose.yaml file in the root directory
of the project.

Then, paste the following into the file.

version: '3.8'
services:
mysql:
container_name: mysql
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=admin1234
networks:
- stack
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-padmin1

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 15/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

interval: 30s
timeout: 10s
retries: 3

application:
container_name: application
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
env_file:
- .env.docker
networks:
- stack
depends_on:
mysql:
condition: service_healthy

networks:
stack:
name: stack
driver: bridge

As you can see, we have created a network named stack . We have created two
services - application and mysql . Both of these services come under the stack
network. In the .env.docker file, I have set the DB_HOST to mysql . This name
corresponds to the name of the service. In the docker file, I have added a
dependency of mysql in application service. This means that the application service
wont start before the mysql service reaches the service_healthy state.

Once done, shut down your previous containers using:

docker stop springboot-test


docker stop temp

Now, we can fire up the entire infrastructure using:

docker compose up

This command will take some time to start up. A few flags that might come in handy:

-d : Starts in detached mode

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 16/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

--build :
Rebuilds the images. Useful when you have made any changes to the
source code.

When you are done playing around with, you can shut down the entire thing by
using:

docker compose down

Conclusion
So that was all about using docker to make your lives easier. I hope you have quiet a
few tricks by now. Feel free to leave a comment in case you find something off.

Top comments (0)

Code of Conduct • Report abuse

AWS PROMOTED

Get a wealth of knowledge from AWS data


experts
Dig in on data questions with expert advice

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 17/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

Let’s Talk About Data is an information gold mine for data professionals looking
for the latest news and guidance on AWS Data & Analytics services and
partners.

Learn More

Rajdip Bhattacharya

Google DSC'22 Core Tech Lead & Cloud Facilitator || Full Stack Developer || Cloud Engineer ||
Game Dev || Cyber Security || Blockchain Developer || Open-source contributor

LOCATION
West Bengal, India
EDUCATION
Narula Institute of Technology
PRONOUNS
He/Him
WORK
Student and Intern
JOINED
Aug 7, 2023

More from Rajdip Bhattacharya

How keyshade employs the use of sockets in distributed environment


#webdev #systemdesign #javascript #programming

Automating Python Deployments with GitHub Actions, AWS ECR, and AWS Lambda
#devops #python #cloud #aws

Building Serverless Python Apps with AWS Lambda and Docker


#devops #docker #aws #cloud

Sentry PROMOTED

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 18/19
7/15/24, 1:31 PM Effortless Containerization: Deploying Spring Boot and MySQL with Docker and Docker Compose - DEV Community

The best way to debug slow web pages


Tools like Page Speed Insights and Google Lighthouse are great for providing advice for front
end performance issues. But what these tools can’t do, is evaluate performance across your entire
stack of distributed services and applications.

Watch video

https://dev.to/thecodersden/effortless-containerization-deploying-spring-boot-and-mysql-with-docker-and-docker-compose-e8n 19/19

You might also like