Docker compose cross containers communication - docker

I'm a very beginner in docker world, and I'm not able to make two containers communicate using docker compose.
I have two containers:
Service Registry: a simple spring boot application using Netflix Eureka to implement a service registry feature.
API Gateway: a simple spring boot application using Netflix Zuul. This application will try periodically to be registered into the Service Registry application by connecting to a given URL
All work fine without docker !!
And now with docker-compose, the gateway is not able to find the Eureka server URL.
docker-compose.yml file:
version: '3.5'
services:
gateway:
build:
context: ../robots-store-gateway
dockerfile: Dockerfile
image: robots-store-gateway
ports:
- 8000:8000
networks:
- robots-net
serviceregistry:
build:
context: ../robots-sotre-serviceregistry
image: robots-sotre-serviceregistry
ports:
- 8761:8761
networks:
- robots-net
networks:
robots-net:
name: custom_network
driver: bridge
The application.yml file of the gateway is:
eureka:
client:
service-url:
default-zone: http://serviceregistry:8761/eureka/
I receive this exception:
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException:
Connection refused (Connection refused)
I tried different ways to configure the Eureka client but no way !! it doesn't work.
Thanks in advance.

I don't exactly why !!! But finally, this works for me:
version: '3.5'
services:
gateway:
container_name: gateway
build:
context: ../robots-store-gateway
dockerfile: Dockerfile
image: robots-store-gateway
ports:
- 8000:8000
hostname: gateway
environment:
eureka.client.serviceUrl.defaultZone: http://serviceregistry:8761/eureka/
serviceregistry:
container_name: serviceregistry
build:
context: ../robots-sotre-serviceregistry
image: robots-sotre-serviceregistry
ports:
- 8761:8761
hostname: serviceregistry
environment:
eureka.client.serviceUrl.defaultZone: http://serviceregistry:8761/eureka/

You didn't set the container name.
Link
And the url or ip should replace to container name.
Example:
mongodb://{container_name}:27017

Related

Docker compose application has not public ports on digitalocean

I have docker compose web app:
version: '3.3'
services:
app:
image: xxxxxxxxxxxxx
restart: always
network_mode: 'host'
image is hidden because of private code
After startup I can call wget http://localhost:4004 on server but once I call PUBLICIP:4004 it doesnt wor, looks like port is not accesable. Firawall is disabled. I am using ubuntu.
Is there any wrong with docker compose?
I tried to google and SO
If you want to publish only port add ports key:
version: '3.3'
services:
app:
image: xxxxxxxxxxxxx
ports:
- "4004:4004"
You can read more here:
https://docs.docker.com/compose/networking/
Probably you will be interested in connecting it to domain and securing by ssl. I recommend you check nginx-proxy-automation.
https://github.com/evertramos/nginx-proxy-automation
I appending below example from my production that works with this library
version: '3'
services:
gql:
image: registry.digitalocean.com/main/xue-gql
ports:
- ${DOCKER_PORT}:4000
env_file:
- .env
environment:
- VIRTUAL_HOST=${HOST}
- LETSENCRYPT_HOST=${HOST}
- VIRTUAL_PORT=${DOCKER_PORT}
command: node ./src/index.js
redis:
image: 'redis:alpine'
networks:
default:
external:
name: ${NETWORK:-proxy}

Best way to prevent direct calls to a microservice hosted in a docker container

I have a simple, proof of concept system that has 2 APIs: one act as the gateway and the other is a microservice. I have created docker containers for both and run them together using a docker compose file.
Everything work well, except I am not sure how to restrict the microservice from being called directly.
Here is my compose file:
version: '3.4'
services:
apigateway:
image: apigateway
container_name: api-gateway
build:
context: .
dockerfile: api_gateway/Dockerfile
ports:
- 7500:7500
networks:
- api-local
apiadmin:
image: apiadmin
container_name: api-admin
build:
context: .
dockerfile: api_admin/Dockerfile
ports:
- 7501:7501
networks:
- api-local
networks:
api-local:
external: true
I can call localhost:7500/some_url and I get back a response. I can also call localhost:7501/some_url and I also get a response. However, I want to prevent clients from calling the 7501 microservice directly. I want all traffic to go through the gateway only.
I can filter the IP in the microservice and reject the connection if not from the gateway IP, but I was wondering if there better approach.
You could try not to expose the microservice port to the host in your docker-compose file, it should be still reachable within the docker network and accessible to the gateway:
version: '3.4'
services:
apigateway:
image: apigateway
container_name: api-gateway
build:
context: .
dockerfile: api_gateway/Dockerfile
ports:
- 7500:7500
networks:
- api-local
apiadmin:
image: apiadmin
container_name: api-admin
build:
context: .
dockerfile: api_admin/Dockerfile
networks:
- api-local
networks:
api-local:
external: true
Please, note I removed the port mapping for the apiadmin service.

How to connect with database(mongodb in server 2) from docker container (running in server 1)

Server 1->10.0.0.47
Server 2->10.0.1.202
All ports between these two servers are open as they are in same VPN in aws
version: '3.3'
networks:
net:
external: true
services:
backend:
image: test/test-backend:prod
ports:
- "8000:8000"
depends_on:
- discovery
ERROR:Connection refused
Note When i try to change the composer like below
connection with mongo established but unable to access the service on port 8000
networks:
net:
external: true
services:
backend:
image: test/test-backend:prod
expose:
- "27017:27017"
ports:
- "8000:8000"
depends_on:
- discovery
The Expose instruction does not change anything, it's for documentation only. You can read more about it in the Dockerfile reference.
If the 2 Server are in the same Docker network, you could change the mongoDB port to 8000 in its installation configuration. Then, you don't need to specify a port etc. in the docker-compose configuration.
If you want to access the mongoDB service from outside, you have to change the docker-compose configuration to:
ports:
- "8000:27017"

Fail to resolve docker compose service name from front end

Hi I'm new to using docker for development. I'm trying to communicate from frontend (react) to the backend (express.js) here.
I have enabled cors as well, I'm getting an error saying net::ERR_NAME_NOT_RESOLVED when trying to fetch from the back end using the url http://backend:4001,
but it's working when I use the docker internal IPAddress, like: http://172.18.0.3:4001.
Following is my docker-compose.yml file.
Please advise on getting this working, thanks.
version: "3"
services:
backend:
build: ./api
volumes:
- ./api:/usr/src/api
ports:
- 6002:4001
depends_on:
- database
database:
image: mongo:4.0.15-xenial
ports:
- 27018:27017
frontend:
build: ./app
volumes:
- ./app:/usr/src/app
ports:
- 6001:3000
links:
- backend
depends_on:
- backend
It will not work, because your browser(internet client) is not part of docker stack network, you have to configure you frontend service to connect to http://localhost:6002 instead of http://backend:4001

how can I communicate between containers?

Im using a container with api gateway in port 80, and I'm needing communicate the api gateway between another containers (all these one using dockerfile and docker-compose). How can I do these others conteiners not expose the port to localhost but communicate internally with the api gateway?
My docker-compose:
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./:/usr/src/app
- /usr/src/app/node_modules
ports:
- "3000:3000"
Solution:
Changed docker-compose file to:
version: '3.5'
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./:/usr/src/app
- /usr/src/app/node_modules
expose:
- "3000"
image: api-name-service
container_name: api-name-service
networks:
- api-network
networks:
api-network:
name: api-network-service
When the services is in the same network, this services can communicate with service name, like "http://api-name-service:3000".
You want to use expose instead of ports:
https://docs.docker.com/compose/compose-file/compose-file-v2/#expose
For example:
services:
app1:
expose:
- "3000"
app2:
...
assuming some API on port 3000 in app1, then app2 would be able to access http://app1:3000/api
Use docker network. Here is a very good tutorial on the docker website on how to use networking b/w containers: https://docs.docker.com/network/network-tutorial-standalone/

Resources