Docker-Compose | Configure docker-compose | Container to Container Communication With Example:

In our previous posts, we have seen how to Dockerize SpringBoot Application (here) and How to pull and push images in Docker Hub (here).

In this post, Let use see about Docker-compose.

What is a docker-compose file?
It is a tool for running multi-container applications. We can configure the services within the docker-compose file and with the help of single command, we will be able to bring up individual containers for each service configured in docker-compose file.

What are we going to do in this post?

  1. We are going to create 2 Spring Boot Applications
  2. We are going to create an image, tag them and push them to docker hub
  3. We are going to create and configure docker-compose file
  4. We are going to deploy the containers using docker-compose in docker swarm mode.

We are going to make a call from SpringBoot_Docker-1 application to SpringBoot_Docker application. When these 2 are deployed as an individual containers, we are going to see how these both containers are going to communicate with each other.

NOTE:
We are going to push and pull the image from docker hub, so if anyone is unaware about how to pull and push the image to/fro docker hub, I would suggest to go through – Docker Hub – Pull and Push Image before proceeding this post further.

Project Structure:

There are certain files which are common to both the projects,

App.java (Same for both the applications)

@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

AppController.java (SpringBoot_Docker)

 

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AppController {
	
	@RequestMapping(value="/docker1")
	public String display() {
		return "Hello World - From SpringBoot_Docker";
	}

}

AppController.java (SpringBoot_Docker-1)

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;


@RestController
public class AppController {
	
	@RequestMapping(value="/docker2")
	public String display() {
		RestTemplate restTemplate = new RestTemplate();
		String s = restTemplate.getForObject("http://helloworld:8080/docker1", String.class);
		return s;
	}
	
	@RequestMapping(value="/docker2/test")
	public String display1() {
		return "Yes working";
	}

}

In the above call, we have used http://helloworld:8080/docker1, Where docker1 is the path of SpringBoot_Docker application. helloworld here is the service name, we can see about this when we configure docker-compose file.

Dockerfile (Same for both the applications)

FROM openjdk:8
MAINTAINER javainfinite
WORKDIR /usr/local/bin
COPY ./target/SpringBoot_Docker-2-0.0.1-SNAPSHOT.jar HelloWorld.jar
ENTRYPOINT ["java", "-jar", "HelloWorld.jar"]

Detailed explanation of Dockerfile is given Here.

Now let us create an image for the above 2 applications and push them to docker hub,

SpringBoot_Docker Application Image Build:

SpringBoot_Docker-1 Application Image Build:

We have successfully pushed our images to dockerhub.

Now let us configure docker-compose file,

docker-compose.yaml

version: '3'
services:
    helloworld:
        image: sriis1987/helloworld_docker2
        networks:
            - javainfinite
        ports:
            - '8086:8080'
    helloworld2:
        image: sriis1987/helloworld_docker2
        networks:
            - javainfinite
        ports:
            - '8085:8080'
            
networks:
  javainfinite:

The above is a simple docker-compose file for this example, there are many other properties that will be included in real time scenario.

Let us understand the docker-compose,

version: ‘3’:
This is the version of docker, We have to follow docker version and we cannot version it by ourselves.

services:
Each application, for example – In our docker-compose we have included 2 spring boot applications, each application is considered as service in docker-compose file.

helloworld and helloworld2:
In docker-compose, we define the applications as services. Here the SpringBoot_Docker is named as helloworld service and SpringBoot_Docker-1 is named as helloworld2 service.

When writing the AppController.java for SpringBoot_Docker-1, we have mentioned this service name in forming the URL. (http://helloworld:8080/docker1)

networks:
This plays an important role in container to container communication. Whenever we build an image and deploy the container for SpringBoot application individually, it will be in bridge network where containers will not be able to communicate with other container.

In docker-compose, by default network will be overlay, where overlay network is required for Container to Container communication.

ports:
We are exposing the external and internal ports for the services for the user.

We can use either Docker in our system or login in play with docker (https://labs.play-with-docker.com/) for deploying the application.

docker swarm init –> This will make the environment to run in Swarm mode.

After this use,

docker-compose up

This will bring up our application.

Now let us hit the API to check whether SpringBoot_Docker-1 able to communicate with SpringBoot_Docker applicaiton.

Code can be downloaded from Here.

By Sri

Leave a Reply

Your email address will not be published. Required fields are marked *