0

I’m new to Docker and have found the following problem in my work these days.

Basically, I have defined two services, for instance, serviceA and serviceB, in docker-compose.yaml and used docker-compose to start these two containers at the same time. Specifically, serviceA is a node.js environment with some JavaScripts written by myself. In addition, there is also a webpack-dev-server in this container for development purpose. serviceB is configured as a python-tornado web server with some self-defined logic to handle HTTP POST request sent from serviceA.

I have created a customized bridge network with the help of docker network. Assume this network is with name mybridge. Then, in the docker-compose.yaml, the two services are both defined to use this customized network. Now, after starting these two services with docker-compose, I can successfully ping serviceB (with name, not serviceB's IP address) from the container of serviceA, and vice versa. But the problem arises when sending HTTP POST request using JS from serviceA. Generally, I just initialized a new request with XMLHttpRequest

request=new XMLHttpRequest();

then

request.open(‘POST’, “http://serviceB:8888/somewhere”, true)

In this case, I get Failed to load resource: net::ERR_NAME_NOT_RESOLVED error in my chrome browser. My guess is that the name serviceB in the http cannot be resolved. But this is weird as ping works. Till this point, both serviceA and serviceB are configured to use dynamically assigned IP addresses. Then if serviceB is changed to real IP address, such as

request.open(‘POST’, “http://172.16.1.20:8888/somewhere”, true)

then it works as intended(the created customized network, mybridge, is configured in the subnet 172.16.1.0/24). With customized docker network, I can configure static IP address, which is 172.16.1.20 in this example, for serviceB in docker-compose.yaml (while serviceA still gets a dynamic IP address) to solve this problem. The question, however, is that why it fails to work with the name under dynamic IP address while ping could work for serviceB?

I googled a lot for this problem during the past few days and failed to find a proper solution. Thus, I created a post here in the hope that someone could provide a helping hand on this problem. More specifics about my docker compose configuration could be provided if required and Thanks in advance.

Keyur Ramoliya
  • 1,900
  • 2
  • 16
  • 17
gerryken
  • 1
  • 3
  • 1
    By default Compose already creates a network between services. Why did you need to make your own? – OneCricketeer Jul 24 '18 at 03:00
  • With the default docker network, IP addresses of services are dynamically assigned. With self-defined network, I can then assign static IP address for serviceB. My problem is that the HTTP POST request now seems to only work with real IP address and using name will cause failure as described in the post. – gerryken Jul 24 '18 at 03:05
  • But why do you want static addresses when you can simply use the service name, which is typically how Docker processes refer to one another – OneCricketeer Jul 24 '18 at 03:10
  • Use service name in my HTTP POST request will cause failure while IP address can work smoothly. And ping name of serviceB from the container of serviceA can work. That's weird from my point and I try to find a good reason or solution to this problem. – gerryken Jul 24 '18 at 03:17
  • As far as I can tell from the question is that it is failing because you overwrite the default network. Did you say it also fails without defining a bridge? Because if so, the error shouldn't be `ERR_NAME_NOT_RESOLVED` – OneCricketeer Jul 24 '18 at 03:20
  • I used the setup with default network in docker compose to check this problem just now. So from both of containers, serviceA and serviceB, it can ping each other with service name smoothly. But when it runs into JS to send HTTP POST, it failed with service name (IP is dynamic at this point) and the error is `net::ERR_NAME_NOT_RESOLVED` reported from my chrome. Weird! – gerryken Jul 24 '18 at 03:45
  • Do you mind adding your compose file to the question? Both versions with and without the network? – OneCricketeer Jul 24 '18 at 03:47
  • I could be wrong, but your XMLHttpRequest is being created by Chrome + Javascript on "the client side", which is outside the container, therefore it's using the hosts DNS, which cannot resolve Docker service networks – OneCricketeer Jul 24 '18 at 03:49
  • Oh, I did a port mapping for serviceA in docker compose `ports: 49000:8080`, so mapping container port 8080 exposed by webpack-dev-server to host machine's 49000. Then I used port 49000 on host Chrome. It could then try the DNS from host which caused the problem. I will check how to fix this. Thanks for the suggestions! – gerryken Jul 24 '18 at 04:00
  • That port number shouldn't be possible https://stackoverflow.com/a/113228/2308683 – OneCricketeer Jul 24 '18 at 04:03
  • 1
    Well, finally I found this https://stackoverflow.com/questions/37242217/access-docker-container-from-host-using-containers-name. Basically, I need to have a DNS-proxy-server on host machine so that container's name could be resolved from host as well. I tried this solution and it works fine :) – gerryken Jul 24 '18 at 06:40
  • That's one option, and how Kubernetes (KubeDNS or CoreDNS) or a Consul based solution would work. But on one machine, you could also just keep your port mapping and use localhost to the port exposed on the host – OneCricketeer Jul 24 '18 at 12:01
  • In our case, it is restricted on one machine according to current plan. So k8s related stuff might be a bit heavy. But that's a good extension if multiple nodes need to be considered in the future. Thanks for your comments @cricket_007 – gerryken Jul 25 '18 at 02:31
  • Well, one machine can die from a random hardware failure, so having redundancy is always a good idea – OneCricketeer Jul 25 '18 at 05:11

0 Answers0