Reputation: 1650
I have 3 simple microservices (mysql, apirest, gui) that I start using docker-compose:
version: '3.2'
services:
mysql:
image: mysql/mysql-server:5.6
container_name: mysql
restart: always
volumes:
- mysql:/var/lib/mysql/data
ports:
- "3306:3306"
networks:
- mynetwork
deploy:
mode: replicated
replicas: 1
environment:
- MYSQL_ROOT_PASSWORD=mypwd
- MYSQL_USER=myuser
- MYSQL_PASSWORD=myuserpwd
- MYSQL_DATABASE=my-db
apirest:
image: .....apirest:latest
container_name: apirest
restart: always
volumes:
- apirest:/apirest/tmp
ports:
- "30000:3000"
networks:
- mynetwork
deploy:
mode: replicated
replicas: 2
gui:
image: ......gui:latest
container_name: gui
restart: always
links:
- apirest
ports:
- "34200:4200"
networks:
- mynetwork
networks:
mynetwork:
volumes:
apirest:
mysql:
The mysql and the apirest microservices can communicate without problem (I can connect to my database from apirest using mysql as hostname.
But I got the following error in the gui microservice as soon as I try to perform an http request (angular) using apirest as hostname:
Failed to load resource: net::ERR_NAME_NOT_RESOLVED
from the gui microservice I can ping the apirest:
docker exec -it gui ping apirest
--- apirest ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.069/0.203/0.338 ms
If I use the public server address (http://serverip:30000/api/test) to perform the http request instead of apirest there is no problem, the http request succeed.
What am I doing wrong??
Thank you
Upvotes: 4
Views: 5131
Reputation: 157
Indeed, as mentioned above, the browser request with ajax is not going through because it is not part of the default network for the containers set up by docker-compose.
However, for development purposes if you still want the gui
microservice to communicate with the apirest
since you have port forwarding for both services in the docker-compose file i.e for gui 34200:4200
and apirest 30000:3000
you can use the bound host ports(on same network) to communicate by having the request url vary depending on where the request comes from.
If the request comes from the apirest container port use the destination url http://apirest:3000/api/test
while if it comes from the browser(host port) use the url http://localhost:30000/api/test
that will forward it to apirest:3000
A simple implementation of this (*using fetch api):
//in the gui microservice
let host,port;
if (window.location.host ==="localhost:34200") {
host="localhost";
port="30000"
}else{
host="apirest";
port="3000"
}
const data = await fetch(`http://${host}:${port}/api/test`,
{
method:"GET"
})
.then(res => res.json())
.then(..)
I used the same thing and was able to view my dockerized application via the browser on localhost for development purposes. I would recommend the use of a proxy above for production.
Upvotes: 0
Reputation: 509
AJAX request is the browser request not the server side request and your browser is not a part of mynetwork. To make ajax request (Client browser need to be public domains or map host file with service node port). You still need to map host file in your browser host machine or use full url with service node port in your gui code.
if you want to avoid using port, proxying is the best way to expose service in my case I am using Nginx
GUI--- ajax req(browser to server req)----> PROXY(NGINX)---(server to server)--> apirest
Upvotes: 15