Communicate between two different applications which reside in two different Docker containers (Vue.js, PHP + MySQL)
Docker is a mechanism that is created to assist both system administrators and the developers , making it a component of many DevOps tool chains. From the developers’ perspective, they can focus on writing code without having any concerns about the system, that it will eventually be running on. It also packages, provisions and runs containers, which are independent of the Operating System.
What is a Docker container?
This is a normalized component, which can be constructed on the fly in order to deploy a specific environment or even an application. A container basically enfolds an application’s software into a hidden box with everything, the application needs to run that comprises the application code, system tools, operating system, run-time, system libraries, and etc. Docker containers are built using Docker images which can be either pulled directly from the dockerhub or can be created manually by using a Dockerfile.
Within this particular use-case, I’m having a Vue.js web application and a MySQL database as different components. The Vue.Js app communicates with a PHP file which contains the back-end related functionalities. As in, the PHP file is the one which interconnects with the MySQL database, and loads the required values from the table, as per the query we define. It exposes the values in the form of an API, so that any front end element in the Vue.js application will be able load those values or rather the result set in the user interface.
Hence in order to make use of the Docker, the above scenario was dockerized by using the docker-compose, where two containers will be created for two different services. One for the vue.js app and the other is for the MySQL database. After dockerizing these services individually, both the containers should be able to communicate between each other. It should be noted that, both the containers should be created within the same network, in order to avoid conflicts during communication between the containers.
- Having a basic web application. In my case it is a Vue.js application. (I have attached the link to my github repository for the entire source-code of this whole use-case)
- Make sure npm is installed. If so, make sure to execute npm install within the directory where package.json file is located, in order to install the necessary node modules for this use-case.
- The vue.js application was built for deployment beforehand by using npm run build.
- Should have a back-end code, to expose APIs’ for the front end to access values from the database. In my case it’s a PHP file which connects to the MySQL database and retrieves values from a given MySQL table.
- Docker CE must be installed.
- Create a Docker Network using the command:
docker network create -d bridge mynet
- After executing the above command, check whether the network has been created:
docker network ls
- Create a Dockerfile in order to setup the necessary environment to deploy the web application. In my case since it was a Vue.js application, I had to pull php:7.2-apache image from the DockerHub in order to run the application using Apache, and to run the PHP file using PHP.
NOTE: The docker file should be named exactly as Dockerfile.
4. Make sure the Dockerfile is being placed within the Vue.js application root directory.
5. After successfully creating the Dockerfile, then we should create the docker compose file in order to create two containers for two different services. Make sure to have two different directories (i.e. one directory for the vuejs application and another for the MySQL scripts.) and to have the docker compose file above those two directories.
Docker-compose is basically used in order to spin up multiple containers at the same time simultaneously rather than building and running images separately. You would really need docker-compose when you have multiple containers to spin up, if not you can simply build and run the image individually.
So in the above docker-compose file, some of the keypoints are:
- Both the services have been created within the same network (mynet)
- Both the services have been given static IPs for this use-case (ipv4_address)
- Depends_on is used, to make sure it executes the services in the correct order. In my case, it executes the mysqldb service first, and then the vuejs.
6. Once the docker-compose.yml file has been created, we can execute the file using the following command:
This command would run the file, and start building the images according to the given order and then it will run those images as two different containers.
7. In order to check whether it has created the images, you can type in the following command:
8. After confirming the respective docker images have been created, we can check whether two containers have been created and they’re running by using the following command:
9. Once the containers are up and running, we can go to the public ip address and view the web application.
10. Once we’re done with everything, we can simply shut down the docker containers by using the following command:
11. We can log into those containers by using the following command:
docker -exec -i -t <container-id> /bin/bash
As for example, we can make sure, whether the database and the table has been created within the MySQL container, by logging into the container and further logging into the MySQL root account.
12. If you want to rebuild the images, make sure to remove the existing images in order to avoid images being created from the cache. In order to remove, the following command can be used:
docker rmi -f <container-id>
The entire source code can be grabbed from myrepo.