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
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 underappacc
so you need to adjust this in the first code bit:You are connecting directly to the container on the container port. Hence the port is
8080
not8081
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
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 accesslocalhost: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
host.docker.internal:8081
which means to use the host network.appacc:8080
so now you wont need 8081 as you are directly calling the container, so thats why 8080