In this post, I will cover the complete guide to using docker compose. You can use it to build a multi-container application. But what is a docker compose and why one should use it?
What is Docker Compose?
If you don’t know what a docker is, you can read about that here. If you have an application that is running on a docker and if that application is using multiple other services like database, web-server, load balancer, then you can write multiple docker files and run multiple containers. It can be cumbersome to manage these files. And if you have to change something, you might have to change in all files.
Docker compose solves this problem by allowing you to write a YAML file to define multiple containers in a single file. You write one docker file and build and run that file for all the containers.
Installing Docker Compose
Based on the definition from docker, docker compose is a tool for defining and running multiple Docker containers.
Depending on your environment, you will have to use the instructions to install docker compose. You will also need docker engine before you can install docker compose. I use the Windows environment, so I will show those instructions here.
- Launch Power shell in administrator mode
- Run this command – [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
- Then run the following command – Invoke-WebRequest “https://github.com/docker/compose/releases/download/1.27.4/docker-compose-Windows-x86_64.exe” -UseBasicParsing -OutFile $Env:ProgramFiles\Docker\docker-compose.exe This will install docker compose. Open a new command prompt and type the first command
docker-compose -v
This should provide the docker-compose version if your installation has run without any issues.
Setting up a Spring Boot application with Docker
To show the power of docker-compose, we will be using a simple To-Do list spring boot app. I will share this app in a GitHub repository along with docker compose file. But this app includes the following applications that we will be using in docker compose:
- Spring Boot application
- Java version 8
- MySQL for database
- Keycloak for Authentication
- Postgres for database
So I won’t show implementing the Spring Boot application. If you want to download this application, you can visit the Github repository or you can read my previous post here.
We will create a docker file for this Spring Boot application and this will run in its own container. Now this application connects to Keycloak and MySQL database for authentication. Keycloak will use Postgres database instead of using the same MySQL database.
The docker file for the Spring Boot application will look like below:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY ./build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
This docker file basically downloads Open JDK 8. It mounts the disk at /tmp
. It copies an application jar file as app.jar
. And of course, it will start the application by running java -jar
.
How to write Docker Compose file
Now comes the docker-compose.yml
file. This will look like below:
version: "3.8"
services:
web:
build: .
ports:
- "8080:8080"
depends_on:
- db
- keycloak
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/todolist?autoReconnect=true&useSSL=false
SPRING_DATASOURCE_USERNAME: betterjavacode
SPRING_DATASOURCE_PASSWORD: betterjavacode
KEYCLOAK_URI: http://keycloak:8180/auth
REALM: SpringBootKeycloakApp
networks:
- common-network
db:
image: mysql:5.7
ports:
- "3307:3306"
restart: always
environment:
MYSQL_DATABASE: todolist
MYSQL_USER: betterjavacode
MYSQL_PASSWORD: betterjavacode
MYSQL_ROOT_PASSWORD: root
volumes:
- db-data:/var/lib/mysql
networks:
- common-network
postgres:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
networks:
- common-network
keycloak:
image: jboss/keycloak
ports:
- "8180:8180"
command: ["-Djboss.socket.binding.port-offset=100"]
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_PASSWORD: password
DB_SCHEMA: public
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: Pa55w0rd
depends_on:
- postgres
networks:
- common-network
networks:
common-network:
driver: bridge
volumes:
db-data:
driver: local
postgres_data:
driver: local
The first line in this docker-compose file is the version of your docker-compose.
services
define different types of services that we will use to build our docker container. web service uses an image that builds from a docker file. In our case, we are building a docker image of our Spring Boot application. This application will run on port 8080. We also have to make sure to pass the required environment variables. As you see in the file, we are using our database as db and the variable SPRING_DATASOURCE_URL
shows that. db is the name of our database service that our application will connect to.
Our database service db
runs on host port of 3307, but uses port 3306 (default port) on the container. This is because I have MySQL running on my host machine at port 3306, so to avoid port conflict, I am using 3307.
We have another database service postgres
in our docker compose file. That uses default ports of 5432 and that’s why not specified here. Keycloak uses postgres as part of this entire application. If you don’t specify postgres, Keycloak will use an in-memory H2 database by default. The problem with an in-memory database is once you stop your container, it will lose all the data. To avoid that, I am using a real database that will save our realm and users’ data.
Another service, that we are using is keycloak
. This is our IDP for authentication. The service is running on port 8180. It uses the Postgres database to connect to. The command part of keycloak service instructs to run the service on port 8180 in the container instead of default 8080.
networks
service defines that all these containers are part of the same network common-network
with a driver of type bridge.
To make sure we can use the database, we need to mount the disk volume for both MySQL and Postgres databases. We mount these volumes locally.
Running the containers
Now to execute the containers with the application, execute the following command (make sure you build your application)
docker-compose up
This will build Docker containers for all our services and start them. Now if we access our application at http://localhost:8080
If a user clicks on Get all tasks
, user will see keycloak login screen as below:
Enter the username and password, and the user will see the tasks for the logged-in user.
Useful commands
docker-compose up
– This command will build the docker containers and start them.
docker-compose up -d
– This is a similar command as above, except it will run all the processes in the background.
docker-compose stop
– Stop the docker services. This will retain the previous state of containers even after you have stopped the containers.
docker-compose start
– Start the docker services
docker-compose logs
– Show the logs from docker containers
docker-compose ps
– List the Docker containers
docker-compose run
– Run one-off command. Example – docker-compose run web env
– List the environment variables of web service.
Advantages of Docker Compose
- By running most of the services in docker, you don’t have to install those services in your environment.
- It’s easier to collaborate the development environment with other developers by checking in the source in version control with docker-compose.
- Quick and easy configuration. You can run your services across platforms.
Advance use of docker compose
Something I have not covered in this post is using network
as a service that you can really extend with docker compose. It also allows you to run a load balancer (or reverse proxy like nginx
) and manage the load with multiple hosts.
Instead of using environment variables, you can also use .env
file for environment variables and load it while starting the containers.
Conclusion
In this post, I showed how you can use docker compose to run multiple containers with a single docker compose file. It also allows you to easily manage your environment.
References
- Docker Compose – docker compose
- Keycloak – Keycloak containers
Top comments (0)