In case you are landing here directly, it’s recommended to read through this documentation first.
Following are the topics, which we shall be touching through this blog :-
- Introduction to Docker-Compose.
- Need of Docker-Compose.
- Forming a simple Docker-Compose File.
- Race-condition in spinning-up docker-containers through docker-compose.
- Launching entire architecture through Docker-compose.
- Checking logs of containers launched through Docker-compose.
- Rolling out changes with Docker-compose fastly.
Question:- What is Docker-Compose ?
Answer:- Docker-Compose will allow us to write a fairly simple text file and that text file is going to contain really all of the information that we have just been typing through the command line (e.g. running the containers, etc).
- It’s all of the configuration data for all of the containers that we need to run our development environments.
- With the help of Docker-compose, we basically define the configuration of our entire running architecture.
Question :- What problem does Docker-Compose is trying to solve for us ?
Answer:- If you recall from our previous blogs, you would realise that, how difficult it is to memorise these cumbersome and complex commands to launch the container.
docker container run -v /Users/B0218162/Documents/LEARNINGS/MEDIUM-BLOG/Docker/DOCKER_LEARN/DATA_DIR_FOR_CONTAINER:/var/lib/mysql -d -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=fleetman --network aditya-network --name mysqldbpanga mysql:5
In order to solve this problem, Docker-Compose can be very helpful.
Question:- How do I check, whether Docker-Compose is installed at my machine ?
Answer:- Docker Compose is a separate software from Docker and depending on what platform you’re running on, we would have to install docker-compose separately.
Question:- How does our entire architecture looks like :-
Answer:- Our architecture looks like :- We have to have TWO containers at runtime and we need them to connect to a particular network.
Question:- With help of Docker-compose, let’s launch now our entire architecture :-
Step #1.) Specifying the version of docker-compose is important :-
Step #2.) Recall that, in previous blog, we created Docker-Image using the maven plugin. Let’s use that very Docker-Image, in order to launch a new Docker-Container.
Step #3.) Now, you can think of each container as being a single standalone service in its own right. A container is some kind of service within your system. We need to define each and every aspect, which we used in the command-line earlier, in order to define a container :-
- In this case, name of our container is : “mysqldbpanga”.
- We shall be using this image, in order to build the container : “mysql:5”.
- This container shall be using the network with name : “aditya-network”.
- We shall also be supplying some environment-variables to be passed to this container : “MYSQL_ROOT_PASSWORD” and “MYSQL_DATABASE”.
- We have also defined the label for the volume as : “aditya-volume”.
Step #4.) Now, we shall be defining the service for the another container :-
- In this case, container-name is : “webappwithmysql-fleetman-cont”.
- We shall be using this image(which we built in previous blog), in order to build the container : “adityagoel123/fleetman-web-with-mysql”.
- This container shall be using the network with name : “aditya-network”.
- The container-port shall be 8080 in this case and same shall be exposed on the host machine at port no. 8084.
- This container would also be connecting to the above container (that we created in step #3) and therefore, this container also depends upon: “mysqldbpanga”. Note that, it’s very important to mention “depends_on” clause in docker-compose file, so as to maintain the startup order.
Concern :- Though we have solved the problem of specifying the orders for the docker-containers to start, however, for startup Compose does not wait until a container is “ready”. For example, container “ webappwithmysql-fleetman-cont” might not really wait untill the container “mysqldbpanga” is really ready.
Solution :- Well there is no ready solution for this RACE-CONDITION so far in Docker-compose Version3. But do note that, there well exists a solution to this on docker-compose Version2. We can only rely on kick of luck and usually, it happens that, mysql based container is usually very fast to start-up and by the time, the webapp based container is started by the docker-compose, the database container is UP & available.
Conclusion :- In real sense, therefore it’s not really possible to control the start-up order of the containers.
The only best, that we can do to solve this problem is to run the “docker-compose up” command multiple times, in case we can’t go through rightly at the first time.
Step #5.) Recall that we created the network manually :-
We shall be creating the docker-network as well through the docker-compose file :-
Step #6.) Recall that we created the label of volume manually earlier blogs. This time, we shall be creating the volumes also through docker-compose :-
Step #7.) Let’s start to create our architecture (i.e. launch our containers) through docker-compose. Before that, how does the final docker-compose file looks like :-
Concern :- Is there an evidence that, TWO docker-containers (as mentioned in aforesaid docker-compose file) are started parallelly ?
Answer:- Yes, well we can see from logs that, logs for both the containers are interwoven and it indicates that containers are started parrallely :-
Concern :- In the above demonstration, if the command is killed, every container shall be killed. Can we also start our containers in the background as well?
Answer:- Yes, well we can start the docker-compose command in background too, by supplying the “-d” option i.e. detached mode.
doocker-compose up -d
Let’s now verify whether really, our containers are up and running :-
Verify #1.) Here are our containers spinned up :-
Verify #2.) Here is our network created :-
Verify #3.) Here is our volume created :-
Verify #4.) Here is how our webapp looks like :-
Verify #5.) Lets verify the logs of MYSQL based container #1 :-
doocker-compose logs -f <SERVICE_NAME>
Verify #6.) Lets verify the logs of Webapp based container #2 :-
Question:- Now, imagine that, there are some changes in code-base of our webapp. How do we make sure that, those changes gets deployed again asap to our deployment-environment ?
Step #1.) Let’s introduce some changes in the JSP file of our webapp :-
Step #2.) Let’s now build the latest jar using :-
Step #3.) Let’s now move this JAR to our docker directory (so that, it gets placed with the Dockerfile) :-
Step #4.) Now, we have to generate a new image using this updated Dockerfile OR We can also use our RUN-CONFIG (docker:build) in IDE :
Step #5.) Let’s verify that, whether new docker-image (for the webapp) got created with execution of step #4:-
Step #5.) Let’s now go ahead and again run the docker-compose :-
docker-compose up -d
Note that, this is the beauty of the “docker-compose up” command that, only the changes shall be picked up magically.
Step #6.) Let’s now verify that, after running the command at step #5, whether the new container has been launched for the webapp :- And Yes there is a new container now :-
Step #7.) Let’s now verify whether changes are now reflecting in the webapp :- We made changes to the title line and that’s very well changed now :-
That’s all in this section. If you liked reading this blog, kindly do press on clap button multiple times, to indicate your appreciation. We would see you in next series.