In the previous article (Click here to visit that article.), we have created, run and linked the docker containers manually. In this article we will explore how to use the docker-compose utility for creating, running and managing the multiple docker containers.
docker compose is a tool for defining and running multi-container Docker applications. With Compose, you use a Compose file to configure your application’s services. Then, using a single command, you create and start all the services from your configuration.In addition, It allows you to define how the image should be built as well.
For this article, we are going to use and modify the same project that is created in the previous article.
In this article, i am just focusing on the docker-compose utility and related features. I am not going to describe, any spring or spring-data-jpa related features here.
First we will clone the source code of the previous article and prepare our development environment. This can be done with following command.
git clone firstname.lastname@example.org:chathurangat/spring-boot-data-jpa-mysql-docker-no-composer.git
Import the project into your preferred IDE and the source code should be appeared as follows.
Lets create the docker-compose.yml file in the root of the project.
docker-compose is a utility/tool that is used to run multi container docker applications. docker-compose utility will read the docker-compose.yml file for setting up the related services for the application. This file should contains the declaration of the services that are required to run the application. If you need to run any service as a separate docker container, then you should declare it in the docker-compose.yml file.
If you just look at the previous project (Click here to visit that article.), you will notice that there were two services those were run on two docker containers. Those services can be listed as:
- mysql service
- application service (spring boot application)
In this article, we are going to explore how to run and manage those two services with docker compose. Please refer the below file to see how those two services has been declared.
lets look at the file structure in detailed.
You can see that the docker compose document version is 3.The syntaxes declare in the docker-compose.yml document will change based on the document version. All the syntaxes that are declared in this document will compatible with version 3.
Setting up mysql container (service)
As you can see that, we have declared the two services here. each service will run in a separate docker container. lets look at each service in detailed as follows.
mysql-docker-container: image: mysql:latest environment: - MYSQL_ROOT_PASSWORD=root123 - MYSQL_DATABASE=spring_app_db - MYSQL_USER=app_user - MYSQL_PASSWORD=test123 volumes: - /data/mysql
we have named the mysql service as mysql-docker-container. (There is no rule and it is possible to select any name for the service)
The mysql:latest image should be used for providing the service. In other words, this image (mysql:latest) will be deployed in the targeted container.
we have declared four environmental variables which will help to initialize the database, create database user and setting up root password.
volume has been defined as /data/mysql. Volumes are the preferred mechanism for persisting data generated by and used by Docker containers.
setting up application container
spring-boot-jpa-app: image: spring-boot-jpa-image build: context: ./ dockerfile: Dockerfile depends_on: - mysql-docker-container ports: - 8087:8080 volumes: - /data/spring-boot-app
The service has been named as “spring-boot-jpa-app“.
The image name is “spring-boot-jpa-image“. If the image does not exist, it should be built with the Dockerfile available in the current working directory. In the previous article, we build the docker image with a manual command. But with docker compose, we can declare the docker image build command as above.
This application service depends on the mysql-docker-container.
The port 8080 of the docker container should be mapped to the port 8087 of the docker host. So the service can be externally accessed with port 8087.
spring-boot-jpa-app container will use the /data/spring-boot-app volume for managing data.
Before running the docker-compose
Now our docker-compose.yml file is ready and it is the time to up the containers with docker-compose. Before moving forward with docker-compose utility, we will look at out Dockerfile related to this project. Dockerfile contains the instructions of how to build the docker image with the source code.
FROM java:8 LABEL maintainer=“email@example.com” EXPOSE 8080 ADD target/spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar ENTRYPOINT ["java","-jar","spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar"]
Just look at the above bold (highlighted) line and you will notice that docker image is built with already built jar file. The Dockerfile does not contains any maven or any other command to build the jar file from the project source code and it continues to build the docker image with already available jar file in the target/spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar. Therefore before moving with building the images or running the containers with docker-compose, we need to build the project artifact (*jar, war or any other related artifact file).
Build the project with maven
The project can be built with following maven command.
mvn clean install -DskipTests
Once the project is built, we can run the docker compose utility to build the targeted images and run the declared services in docker containers.
“docker-compose” to build the images and run services in docker containers
In the command line, go to the project directory where your docker-compose.yml file is located. Then run the following docker compose command to run the declared services (in docker-compose.yml) in docker containers.
You can see that we have declare some command to build the docker image for a specific service (spring-boot-jpa-app) with docker-compose. Therefore it will build the declared image before up and running the docker services in the containers. you can run the following command to check whether the image is successfully built.
This will display a list of available images as follows.
If you just observe the first line of the screenshot, you can see that the image (spring-boot-jpa-image) has already been created.
It will take few seconds to build the image and up the containers for the declared/given services. Once above process is completed, you may run the following command to check whether the containers are up and running.
It will display a list of up and running docker containers are as follows.
Testing the application
Now everything is up and running. You can follow the testing instructions given in the previous article (click here to go to the previous article) to test the application.
Rebuilding the docker image
Most of the time you may need to rebuild the project. (due to source code and application logic changes). In such cases, you need to rebuild the docker image too. If you do not rebuild the docker image, the docker image repository may contain the older image version. Therefore the docker-compose will use the older image version available in the docker repository to run the service container. In order to avoid this issue, we need to rebuild the docker image. This can be done with following command.
Is it enough to run the “docker-compose build” once the source code is changed?
No. “docker-compose build“ will build the docker image using the available project final build file (jar, war etc..). So if you have modified the source code of the project, you need to rebuild the project with maven.
Once the project is build, you can run the docker-compose build command to build the docker image.