Docker Compose For Spring Boot with MongoDB
- Chinthaka Dinadasa
- 17 Jan, 2021
In this article, I’ll explain how we can set up a deployment using docker-compose for a Spring Boot application that uses a MySQL database.
Technology stack which going to use in this tutorial,
- Spring Boot 2.4.1-RELEASE
- Spring Data JPA
- MySQL – 8.0
- Lombok
- Docker – version 19.03.14
- Docker-Compose – version 1.27.4
- IntellijIdea for IDE
Prerequisites,
You need to setup docker and docker-compose in your machine to go forward with this tutorial.
I’ve used following well-written articles from DigitalOcean to set up both docker and docker-compose on my local setup.
Setting Up MySQL Base Project
I’ve created a simple REST API using Spring Boot with MySQL database usage. First download or clone from GitHub.
$ git clone https://github.com/javatodev/spring-boot-mysql-base-project.git
Or else you can skip this step and try a docker-compose set up with your own spring boot application which uses MySQL database.
Setup Docker Image For Spring Boot Application
In this tutorial, our docker-compose setup using two main services or components. Those are the Spring Boot application and MySQL database.
MySQL is already available as a docker image from docker hub MySQL page. You can just go and select the version you need from there.
But your project is still not pushed or published as a docker image. Hence first you need to have docker image for your spring boot application. Then you can use both app and DB images with docker-compose.
If you don’t have a good understanding of how to use docker with a spring boot application, you can refer our article on How to Dockerize Spring Boot Application.
OK Let’s start the docker image creation,
First, create a file naming as Dockerfile in your project root folder. Then copy the following content into that file.
FROM openjdk:8-jdk-alpine
LABEL maintainer="author@javatodev.com"
VOLUME /main-app
ADD build/libs/spring-boot-mysql-base-project-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar","/app.jar"]
Now you have two ways of building docker-compose setup.
-
Pointing Dockerfile into the docker-compose setup.
-
Giving created docker image to the docker-compose setup.
Let’s go forward with pointing docker file way, since giving docker image part will cover with MySQL image in this same setup.
Docker Compose File With Spring Boot and MySQL
Now our application has the instruction to building the Docker image. So let’s create the docker-compose.yml file which allows us to combine the Spring Boot application and MySQL database in this setup.
First, go to the project root and create a file named docker-compose.yml
Using links to Build Communication Between Services.
There are two ways of building communication between the spring boot application and the MySQL database. You can use one of the following two methods to build this docker-compose setup.
I’ll start with using links to build communication between both. So add the following content into the docker-compose.yml file,
version: "3.7"
services:
api_service:
build: .
restart: always
ports:
- 8080:8080
depends_on:
- mysql_db
links:
- mysql_db:app_db
mysql_db:
image: "mysql:8.0"
restart: always
ports:
- 3306:3306
environment:
MYSQL_DATABASE: java_to_dev_app_db
MYSQL_USER: java_to_dev
MYSQL_PASSWORD: nE5kMc7JCGNqwDQM
MYSQL_ROOT_PASSWORD: nE5kMc7JCGNqwDQN
Here we have out two main services as,
-
api_service – Spring Boot REST API which runs on port 8080.
-
mysql_db – MySQL DB which runs on port 3306
Explanation about the configurations I have used in this docker-compose file,
build – Here we should introduce the image name to build under that service, Here we have our Dockerfile which was developed for the API in the same level with docker-compose.yml so using “.” it will capture that docker file and build the handle the api_service when executing this file.
Additionally, we have introduced mysql:8.0 as the docker image for MySQL DB. It will download from docker registry and start when needed.
More to research: We can do the same to spring boot API docker image as well, Just push that image to docker-hub and you can directly use given image name and version for this setup as well.
restart – always Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted.
ports – Here we are mapping local machine port along with port inside a docker container.
links – Here we are setting a link with app_db service. So we can use database when defining IP address for the database connection on our spring boot application. Then it will connect with the database running with this docker-compose.
environment – In this section, we are setting the MySQL database name, MySQL username and password for the application and root password.
All done, Now let’s change our application.properties to support this database and application server setup.
spring.datasource.url=jdbc:mysql://app_db:3306/java_to_dev_app_db
spring.datasource.username=java_to_dev
spring.datasource.password=nE5kMc7JCGNqwDQM
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=always
Here as you can see we are using that link value we used in docker-compose definition for host/IP address. additionally, password and DB has changed accordingly.
Better Solution: Use a separate application.properties file for docker-compose based deployments and set that via profiles.
Using Depends On to Build Communication Between Services
The docker-compose documentation specifies that links
is deprecated and should be replaced with depends_on
.
So here I’m setting the same docker-compose setup with using depends_on flag.
Just add the following to the docker-compose.yml
version: "3.7"
services:
api_service:
build: .
restart: always
ports:
- 8080:8080
depends_on:
- mysql_db
command: sh -c './wait-for mysql_db:3306 -- npm start'
mysql_db:
image: "mysql:8.0"
restart: always
ports:
- 3307:3306
environment:
MYSQL_DATABASE: java_to_dev_app_db
MYSQL_USER: java_to_dev
MYSQL_PASSWORD: nE5kMc7JCGNqwDQM
MYSQL_ROOT_PASSWORD: nE5kMc7JCGNqwDQN
Here we are using depends_on to set dependent services to api_service. So internally docker-compose will start dependency services first and it will start dependent services in the end. So basically here it will start the DB first and finally, the application will be started.
Additionally, we have a small change on database connection properties, Here you should add the service name for the host or IP on that database connection.
spring.datasource.url=jdbc:mysql://mysql_db:3306/java_to_dev_app_db
spring.datasource.username=java_to_dev
spring.datasource.password=nE5kMc7JCGNqwDQM
spring.jpa.hibernate.ddl-auto=update
spring.datasource.initialization-mode=always
Running Spring Boot Application and MySQL Database Using Docker Compose
Now we have our docker-compose setup for this application. So first create a jar build for this application using the following command,
Navigate to application root folder and execute,
$ ./gradlew clean build
Now there should be a newly created jar file with all the necessary files to run this application on build/libs folder.
create the build with docker compose to build docker image using built jar file.
$ docker-compose build
use the following command to run the whole setup using docker compose.
$ docker-compose up
Then It will capture the docker-compose.yml and start running using the instructions given in that file.
sample output:
Conclusion
Thanks for reading our latest article on Docker Compose Spring Boot with MySQL with practical usage. Hope you got a good understanding of how we can use docker, and docker-compose with spring boot application development and deployment.
If you are looking for spring boot based practical application development tutorials, just check our article series and comment on whatever new things you need to see on our website.
You can get docker-compose.yml and Dockerfile from GitHub gists.
Related Articles,