Docker compose and Service communication - node.js

I have a docker-compose with 5 services that have to communicate.
I checked whether they would be in the same network using docker network inspect networkname_dafult
and I could find all the apps there in the same network.
The result of inspect returned a json with a name property.
```"Name": "app_1",```
In each service I am using that name to make http requests but they return
"connect ECONNREFUSED 127.0.0.1:5003" for example.
If I access localhost:5003 it works, and it will work for each service.
If i try to make the http requests from my apps using localhost:port it wont work either.
My dockercompose.yml
version: "3.7"
services:
App1:
image: user/app1
ports:
- 5001:5001
links:
- App2
- App3
- App4
- App5
hostname: app1
App2:
image: user/app2
ports:
- 5002:5002
hostname: app2
App3:
image: user/app3
ports:
- 5003:5003
hostname: app3
App4:
image: user/app4
ports:
- 5004:5004
hostname: app4
App5:
image: user/app5
ports:
- 5005:5005
hostname: app5
I tried to make the http requests using the hostname, Appx and etc... I cant make them communicate with each other.
What might I be missing here?

Create a network and assign all the parts of the service to that network. One example:
version: '3.7'
networks:
app_net:
driver: bridge
services:
App1:
image: user/app1
ports:
- 5001:5001
networks:
- app_net
hostname: app1
App2:
image: user/app2
ports:
- 5002:5002
networks:
- app_net
hostname: app2
App3:
image: user/app3
ports:
- 5003:5003
networks:
- app_net
hostname: app3
App4:
image: user/app4
ports:
- 5004:5004
networks:
- app_net
hostname: app4
App5:
image: user/app5
ports:
- 5005:5005
networks:
- app_net
hostname: app5
But it might be that I'm missing something. Another thing to consider is using links - more info here. Also, if you are going to copy+paste this code, take care about indentation.

Docker-compose already creates a default network.
I ran docker network ls to see which networks were available
and used docker network inspect mynetwork to see if the apps on my docker-compose were running on the same network (They will be).
The result of docker network inspect is an array of containers objects.
Each container object has a name property (That was the information I nedded to make http connections between services)
"Containers": {
"01fcacc2b2dc8450c5c75e": {
"Name": "myapp_1",
"EndpointID": "9e3fa9633d9d1692d4f7120c",
"MacAddress": "00:00:00:00:00:00",
"IPv4Address": "172.33.0.2/16",
"IPv6Address": ""
},
On each service I was performing http requests I used that property name to make the requests.
axios.get(http://myapp_1)
An important detail was to rebuild my container after changing it!
docker build -t myapp .
When I ran docker-compose again everything worked.

Related

Can't Access Traefik dashboard outside server

I am learning traefik and I am trying to connect to Ubuntu server hosted on a raspberry pi, Traefik is running on Docker. Currently I just want to access the dashboard, however am unable to access it outside my server but can ping it from inside the server itself,
This is how my traefik.yml file looks like
api:
dashboard: true
insecure: true
entryPoints:
http:
address: ":80"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
docker-compose file
services:
proxy:
image: traefik
networks:
- traefik
ports:
- "80:80"
- "8080:8080"
command:
- "--api.insecure=true"
- "--api.dashboard=true"
- "--providers.docker"
- "--log.level=DEBUG"
- "--configFile=/home/ubuntu/traefik/traefik.yml"
volumes:
- $PWD/traefik.yml:/home/ubuntu/traefik/traefik.yml
- $PWD/acme.json:/home/ubuntu/traefik/acme.json
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
networks:
traefik:
external:
name: traefik
I have docker network registered called traefik
NETWORK ID NAME DRIVER SCOPE
...
ef66....... traefik bridge local

Azure web app multi container (MEAN app), what is the URL to connect to node backend container from front end container?

Trying to learn to deploy angular app to azure web app using multi-container, the frontend loads fine but cant connect to the backend node container, I want to add the url of the node backend to my angular frontend but i cant figure out what it is. I've tried https://rojesh.azure.io:3000, https://rojesh.azurewebsites.net:3000, http://server:3000 and more but nothing seems to work. Website Hostname: https://rojesh.azurewebsites.net and the acr name is rojesh.azurecr.io which has 3 images. This is my config file for compose in azure:
version: '3.3'
services:
db:
image: rojesh.azurecr.io/db:latest
ports:
- "27017:27017"
restart: always
networks:
- app-network
server:
image: rojesh.azurecr.io/server:latest
depends_on:
- db
ports:
- "3000:3000"
restart: always
networks:
- app-network
app:
depends_on:
- server
image: rojesh.azurecr.io/app:latest
environment:
NGINX_HOST: rojesh.azurewebsites.net
NGINX_PORT: 80
ports:
- "80:80"
restart: always
networks:
- app-network
networks:
app-network:
driver: bridge
The app works fine locally using docker compose which is:
version: '3.9'
services:
docker-app:
build:
context: app
dockerfile: Dockerfile.dev
ports:
- '4200:4200'
volumes:
- ./app/src:/app/src
docker-server:
build:
context: server
dockerfile: Dockerfile
environment:
PORT: 3000
MONGODB_URI: mongodb://mongo:27017/rojesh
JWT_SECRET: secret
ports:
- 3000:3000
depends_on:
- mongo
volumes:
- ./server:/server
mongo:
container_name: mongo-server
image: mongo:latest
ports:
- 27017:27017
Thanks # ajkuma-msft. Azure App Service only exposes ports 80 and 443. Yes, incoming requests from client would just be over 443/80 which should be mapped to the exposed port of the container.
App Service will attempt to detect which port to bind to your container. If you want to bind to your container the WEBSITES_PORT app setting and configure it with a value of the port.
Web App for Containers currently allows you to expose only one port to the outside world. The container can only listen for HTTP requests on a single port.
From Docker compose configuration stand-point : Ports other than 80 and 8080 are ignored.
Refer Docker Compose options lists shows supported and unsupported Docker Compose configuration options.
Refer here

Connecting to a neo4 driver (in a Docker container) from another Docker container

Normally I'd have an instance neo4j running in Docker, then in a script I access the driver like so:
self.driver = GraphDatabase.driver(uri="bolt://localhost:7687", auth=("username", "password"))
I'm now putting this script itself into a Docker container, but I now get the error message:
neo4j.exceptions.ServiceUnavailable: Failed to establish connection to IPv6Address(('::1', 7687, 0, 0)) (reason [Errno 99] Cannot assign requested address)
What uri (or other parameter) needs changing to access a neo4 Docker instance, from another docker container?
Within my docker-compose.yml, I have:
version: '3'
services:
neo4j:
container_name: neo4j
image: neo4j:3.5
restart: always
environment:
- NEO4J_dbms_memory_pagecache_size=2G
- dbms_connector_bolt_tls__level=OPTIONAL
- NEO4J_dbms_memory_heap_max__size=3500M
- NEO4J_AUTH=neo4j/start
volumes:
- $HOME/neo4j/data:/data
- $HOME/neo4j/logs:/logs
- $HOME/neo4j/import:/import
- $HOME/neo4j/plugins:/plugins
ports:
- 7474:7474
- 7687:7687
appgui:
container_name: appgui
image: python:3.7.3-slim
build:
context: ./APPGUI/
volumes:
- ./APPGUI/:/usr/src/app/
restart: always
environment:
PORT: 5000
FLASK_DEBUG: 1
ports:
- 80:80
depends_on:
- neo4j
I also can't access my web app (http://localhost:5000)
Your service can't connect to localhost Neo4j, because it is inside a docker container, and localhost points to the docker containers instead of your local machine.
In this case, it is best to run both containers with docker-compose. You want to set the depends on feature in the other docker container. Here is an example docker-compose.yml file from my project.
version: '3.7'
services:
neo4j:
image: neo4j:4.1.2
restart: always
hostname: neo4jngs
container_name: neo4jngs
ports:
- 7474:7474
- 7687:7687
api:
build:
context: ./API
hostname: api
restart: always
container_name: api
ports:
- 3000:3000
depends_on:
- neo4j
As you can see, the api container is a service that will connect to Neo4j. Now you can change the driver settings to:
self.driver = GraphDatabase.driver(uri="bolt://neo4j:7687", auth=("username", "password"))
And you are good to go.
I solved it and it was actually a dumb mistake, but one that could happen to others I guess...
In the docker-compose.yml:
build: ./APP1/
needs to be in quotes, so:
build: './APP1/'
However Tomaž Bratanič provided me with some helpful tips to get a resolve.

Communication between microservices with docker-compose and traefik

I have a microservice based node app. I am using docker, docker-compose and traefik for service discovery.
I have 2 microservices at this moment:
the server app: running at node-app.localhost:8000
the search microservice running at search-microservice.localhost:8002
The issue I can't make a request from one microservice to another.
Here are my docker compose config:
# all variables used in this file are defined in the .env file
version: "2.2"
services:
node-app-0:
container_name: node-app
restart: always
build: ./backend/server
links:
- ${DB_HOST}
depends_on:
- ${DB_HOST}
ports:
- "8000:3000"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:node-app.localhost"
reverse-proxy:
image: traefik # The official Traefik docker image
command: --api --docker # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
- "8080:8080" # The Web UI (enabled by --api)
volumes:
- /var/run/docker.sock:/var/run/docker.sock
search-microservice:
container_name: ${CONTAINER_NAME_SEARCH}
restart: always
build: ./backend/search-service
links:
- ${DB_HOST}
depends_on:
- ${DB_HOST}
ports:
- "8002:3000"
labels:
- "traefik.port=80"
- "traefik.frontend.rule=Host:search-microservice.localhost"
volumes:
node-ts-app-volume:
external: true
Both the node-app and the search-microservice expose the port 3000.
Why can't I call http://search-microservice.localhost:8002 from the node app ? calling it from the browser works though.
Because node-app is a container and to access other containers it has to use service name and internal port.
In your case it is search-microservice:3000.
To access host PC and exposed ports, you have to use host.docker.internal name for all services and external port.
If you want to access other services from in a different container with their hostnames, you can use the "extra_hosts" parameter in your docker-compose.yml file. Also, you have to use the "ipv4_address" parameter under the network parameter for each all services.
For example;
services:
node-app-1:
container_name: node-app
networks:
apps:
ipv4_address: 10.1.3.1
extra_hosts:
"search-microservice.localhost:10.1.3.2"
node-app-2:
container_name: search-microservice
networks:
apps:
ipv4_address: 10.1.3.2
extra_hosts:
"node-app.localhost:10.1.3.1"
Extra hosts in docker-compose

Docker from a container calls to another container (Connection Refused)

I have container for two NodeJS services and one Nginx for reverse-proxy.
I have make NGINX on port 80 so it's publicly available via localhost on my browser
I also use reverse-proxy to proxy_pass to each responsible service.
location /api/v1/service1/ {
proxy_pass http://service1:3000/;
}
location /api/v1/service2/ {
proxy_pass http://service2:3000/;
}
In my service 1, there is an axios module that wants to call to service 2 by making a request to localhost/api/v1/service2
But, it says that connection is refused. I doubt if the localhost in service 1 refer to its container, not the docker host.
version: '3'
services:
service1:
build: './service1'
networks:
- backend
service2:
build: './service2'
networks:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
networks:
backend:
driver: bridge
Even after using network, it still says ECONNREFUSED.
Please help.
Try adding the depends_on in your docker-compose file for the nginx, like below:
version: '3'
services:
service1:
build: './service1'
expose:
- "3000"
networks:
- backend
service2:
build: './service2'
expose:
- "3000"
networks:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
depends_on:
- service1
- service2
networks:
backend:
driver: bridge
This would make sure that both services are running first before the nginx container attempts to connect to them. Perhaps the connection is refused because the nginx container keeps crashing due to it not finding the two services running when it executes its conf file and connect to the backends.

Resources