In this tutorial, you will learn how to deploy a Spring Boot application and a MySQL server in separate Docker containers. By the end of this tutorial, you will know how to run your Spring Boot application in one Docker container and your MySQL server in another Docker container and how to make them communicate with each other.
To learn more about Docker, please check other Docker tutorials for Beginners.
What You’ll Learn:
- How to create a Spring Boot application.
- How to setup MySQL server in a Docker container.
- How to setup the Spring Boot application in another Docker container.
- How to enable communication between the two Docker containers.
Prerequisites:
Before we start, you need to have these installed on your computer:
- Java Development Kit (JDK)
- Docker
- IntelliJ IDEA or any IDE you prefer
Creating our Spring Boot Application
First, let’s create our Spring Boot application using Spring Initializr. Open Spring Initializr in your browser. For the Project metadata, use these values:
- Group: com.example
- Artifact: dockerdemo
- Packaging: Jar
- Java: 11
Under Dependencies, select Spring Web
, Spring Data JPA
and MySQL Driver
. Then, click on the Generate
button to download the project. Unzip and open it in your IDE.
In the src/main/java/com.example.dockerdemo
package, create a new Java class named UserEntity
with these fields: firstName, lastName, email, password. Annotate this class with @Entity
to make it a JPA entity and @Table(name = "users")
to map it with the ‘users’ table in the MySQL database.
Next, create a UserRepository
interface in the same package, which extends JpaRepository<UserEntity, Long>
. This interface will provide us with basic CRUD operations for the UserEntity
.
Finally, create a UserController
class annotated with @RestController
. Add a /users
POST API endpoint which accepts user details in JSON format and stores it in the database using UserRepository
.
Setting up MySQL Server in a Docker Container
The second step involves setting up our MySQL server in a Docker container. Normally, this would require a Dockerfile. However, we are going to use a more flexible approach, a docker-compose.yml
file to define our MySQL service. This file allows us to manage multiple services more efficiently.
The docker-compose.yml
file should be created in the root directory of your Spring Boot project, where your pom.xml
file resides. This is crucial because Docker-compose works in the context of this directory, also known as the project root directory.
Here’s what you need to do:
Create a new file named docker-compose.yml
in the root directory of your Spring Boot project and paste in the following content:
version: '3.1' services: db: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: testdb MYSQL_USER: user MYSQL_PASSWORD: password ports: - 3306:3306 volumes: - db_data:/var/lib/mysql volumes: db_data: {}
This script will perform several actions. It will:
- Pull the MySQL 8.0 image from Docker Hub.
- Create a new MySQL server.
- Set the root password as ‘root’.
- Create a new database named ‘testdb’ along with a user named ‘user’ and a password ‘password’.
- Expose the MySQL server on port 3306.
- Persist the data on a Docker volume named ‘db_data’ to ensure data is not lost when the container stops.
Setting up Spring Boot Application in a Docker Container
To package our Spring Boot application inside a Docker container, we first need a Dockerfile. Create a new file named Dockerfile
in the root directory of the project with the following content:
FROM openjdk:11 ADD target/dockerdemo-0.0.1-SNAPSHOT.jar dockerdemo.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "dockerdemo.jar"]
This Dockerfile does the following:
- Uses
openjdk:11
as the base image. - Adds the output jar file
dockerdemo-0.0.1-SNAPSHOT.jar
from thetarget
directory to the Docker image and renames it todockerdemo.jar
. - Exposes port 8080.
- Specifies the command to start our Spring Boot application.
Before building our Docker image, we need to package our application into a jar file. Open the terminal in the project root directory and execute: ./mvnw clean package
.
Now, we can build our Docker image using: docker build -t dockerdemo .
Enabling Communication Between the Two Docker Containers
We’ve successfully setup our Spring Boot application and MySQL server in separate Docker containers. Now, we need to make them communicate with each other.
Go back to docker-compose.yml
and add another service for our Spring Boot application:
version: '3.1' services: db: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: testdb MYSQL_USER: user MYSQL_PASSWORD: password ports: - 3306:3306 volumes: - db_data:/var/lib/mysql web: image: dockerdemo build: context: . dockerfile: Dockerfile ports: - 8080:8080 depends_on: - db environment: SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/testdb SPRING_DATASOURCE_USERNAME: user SPRING_DATASOURCE_PASSWORD: password SPRING_JPA_HIBERNATE_DDL_AUTO: update volumes: db_data: {}
This file accomplishes the following:
- Sets up a MySQL database in a Docker container, just like we did in Step 2. The MySQL server is exposed on port 3306, and the data is persisted on a Docker volume named ‘db_data’.
- Sets up the Spring Boot application in another Docker container. It uses the Dockerfile in the current directory to build the Docker image for the Spring Boot application, and then runs the application, exposing it on port 8080.
- The
depends_on
attribute ensures that the ‘db’ service (the MySQL server) starts before the ‘web’ service (the Spring Boot application). - Environment variables are set for the ‘web’ service to connect to the ‘db’ service. The
SPRING_DATASOURCE_URL
points to the ‘db’ service, andSPRING_DATASOURCE_USERNAME
andSPRING_DATASOURCE_PASSWORD
provide the credentials for connecting to the MySQL server.
With this setup, running docker-compose up
in the terminal will start both services. The Spring Boot application will be accessible at localhost:8080
and it will be able to interact with the MySQL server running in a separate Docker container.
Congratulations! You have successfully deployed a Spring Boot application and a MySQL server in separate Docker containers and enabled communication between them.