skip to Main Content

I have two Java Spring Boot applications:
On port 8080:

@SpringBootApplication
@RestController
public class LogonPageApplication {
    private static final String PROCESS_STRING_URL = "http://localhost:8081/processString";

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

    @GetMapping("/send")
    public String test() {

        String responseBody = "";
        try {
            RestTemplate restTemplate = new RestTemplate();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            String requestBody = "{testttgfvrdf}";
            HttpEntity<String> httpEntity = new HttpEntity<>(requestBody, headers);

            ResponseEntity<String> response = restTemplate.exchange(PROCESS_STRING_URL, HttpMethod.POST, httpEntity, String.class);

            responseBody = response.getBody();
        } catch (Exception e) {
            return e.getMessage();
        }

        return "Main Pagen" + "Response from /processString: " + responseBody;
    }

}


On port 8081:

@SpringBootApplication
@RestController
public class AcceptMessageApplication {

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

    @PostMapping("/processString")
    public String processString(@RequestBody String inputString) {
        return "Processed string: " + inputString;
    }

}

I have two Dockerfiles:

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/AcceptMessage-0.0.1-SNAPSHOT.jar /app/AcceptMessage-0.0.1-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "AcceptMessage-0.0.1-SNAPSHOT.jar"]

With filenames beeing the only differences

And a docker-compose file:

version: '3'
services:
  appacc:
    build:
      context: AcceptMessage
      dockerfile: Dockerfile
    ports:
      - "8081:8080"
    networks:
      - my-network
  applog:
    build:
      context: LogonPage
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    networks:
      - my-network
networks:
  my-network:

# docker-compose build
# docker-compose up

This app works as intended when I run it from a console and so does the endpoint when sending a requst via Postman, however I cannot get them to exchange message having dockerized it whenever I enter http://localhost:8080/send resulting in:

I/O error on POST request for "http://localhost:8081/processString": Connection refused.

2

Answers


  1. Localhost inside a container is not the same as localhost outside of a container. Hence you cannot reference the other container like this.

    Luckily since you are using docker-compose in the way that you are,you can just directly connect to it under appacc so you need to adjust this in the first code bit:

    @SpringBootApplication
    @RestController
    public class LogonPageApplication {
        private static final String PROCESS_STRING_URL = "http://appacc:8080/processString";
    
        public static void main(String[] args) {
            SpringApplication.run(LogonPageApplication.class, args);
        }
    
    

    You are connecting directly to the container on the container port. Hence the port is 8080 not 8081 as that would be what you’re mapping to on the host port. Theoretically you could drop that mapping from the docker-compose unless you still want to reach the containers from the host as well.

    Small note: you don’t need to manually create a network unless you explicitly want to reference it since the documentation states the following

    By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

    Login or Signup to reply.
  2. You need to understand 8081:8080 means to map your local machines port 8081 to your container’s port 8080. And then from other container you are trying to access localhost:8081 which means it is trying to reach the 2nd container’s network, not your local/host machine’s network. A container cannot access your machine’s network through localhost.

    There are 2 ways for this

    1. Not the best way: use host.docker.internal:8081 which means to use the host network.
    2. The best approach As both containers are already on same network so use the other container’s name and container’s port, so in your case appacc:8080 so now you wont need 8081 as you are directly calling the container, so thats why 8080
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search