Connecting to a neo4 driver (in a Docker container) from another Docker container - python-3.x

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.

Related

Can't access MongoDB container from NodeJS App

I'm running an instance of a web application in my Docker container and am also running a MongoDB container so when I launch the web app I can easily connect to the DB on the app's connection page.
The issue is that I'm not sure how to reach the Mongo container from my web app and am not sure if my host/port connection info is correct.
My Docker Setup
As you can see the container is up and running with both mongo and web app services running without errors
I build the two through docker-compose.yml
version: "3.3"
services:
web:
image: grafana-asw-v3
container_name: grafana-asw-v3
restart: always
build: .
ports:
- "13000:3000"
volumes:
- grafana-storage:/var/lib/grafana
stdin_open: true
tty: true
db:
container_name: mongo
image: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
volumes:
- grafana-mongo-db:/var/lib/mongo
ports:
- "27018:27017"
volumes:
grafana-mongo-db: {}
grafana-storage: {}
Issue
With everything up and running I'm attempting to connect through the web app, but I seem to be using the wrong connection info...
I assumed to use "hostMachine:port" (roxane:27018), but it's not connecting. Is there something I overlooked here?
There were two changes I had to make to fix this issue:
Modify the bind_ip in mongod.conf via making this change to my docker-compose file
db:
container_name: mongo
image: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
volumes:
- grafana-mongo-db:/var/lib/mongo
ports:
- "27018:27017"
command: mongod --bind_ip 0.0.0.0
I needed to refer to the IP address instead of the hostname in the cli in my we application. (Thanks to this answer for help with this one)
Short answer
db service is in the same network than web service not in host network.
As you named your services via container_name you shoud be able to use the connection string mongodb://mongo:27017
Explanation
By default, docker containers run under a bridge network allowing them to communicate without viewing your host network.
When using ports in a compose file, you define that you want to map an internal port of the container to the host port
"27018:27017" => I want to expose the container port number 27017 to the host port number 27018.
As a result, you could expose your web frontend without exposing your mongo service :
version: "3.3"
services:
web:
image: grafana-asw-v3
container_name: grafana-asw-v3
restart: always
build: .
ports:
- "13000:3000"
volumes:
- grafana-storage:/var/lib/grafana
stdin_open: true
tty: true
db:
container_name: mongo
image: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
volumes:
- grafana-mongo-db:/var/lib/mongo
volumes:
grafana-mongo-db: {}
grafana-storage: {}

Calling service from one docker container to other container is causing net::ERR_NAME_NOT_RESOLVED

i am running application with multi containers as below..
feeder - is a simple nodejs container from image node:alpine
api - is nodejs container with expressjs from image node:alpine
ui-app - is react app container from image node:alpine
i am trying to call the api service in ui-app i am getting error as below
image to Console Log
image to Console Log
not sure what is causing the problem
if i access the services as http://192.168.99.100/ping it works (that is my docker machine default ip)...
but if i use container name like http://api:3200/ping it is not working...? please help..
the below is my docker-compose.
version: '3'
services:
feeder:
build: ./feeder
container_name: feeder
tty: true
depends_on:
- redis
links:
- redis
environment:
- IS_FROM_DOCKER=true
ports:
- "3100:3100"
networks:
- hmdanet
api:
build: ./api
container_name: api
tty: true
depends_on:
- feeder
links:
- redis
environment:
- IS_FROM_DOCKER=true
ports:
- "3200:3200"
networks:
hmdanet:
aliases:
- "hmda-api"
ui-app:
build: ./ui-app
container_name: ui-app
tty: true
depends_on:
- api
links:
- api
environment:
- IS_FROM_DOCKER=true
ports:
- "3000:3000"
networks:
- hmdanet
redis:
image: redis:latest
ports:
- '6379:6379'
networks:
- hmdanet
networks:
hmdanet:
driver: bridge
You can only use service name as a domain name when you are inside a container. In you case it's your browser making the call, it does not know what api is. In you web app, you should have an env like base url set to the ip of your docker machine or localhost.

External link is not working in Docker Compose

I have two docker-compose.yml files. In the first one, I run a mongodb instance:
version: '3'
services:
mongodb:
image: mongo:latest
container_name: "mongodb"
volumes:
- ./data/db:/data/db
ports:
- 27017:27017
In the second one, I run my web app and I want to link it with mongodb container:
version: '3'
services:
webapp:
build:
context: .
external_links:
- mongodb
ports:
- 8080:8080
But, when I run my webapp, I get a connection error. I'm connecting to this URI:
const DB_URI = 'mongodb://mongodb:27017/mydb';
but I get MongoNetworkError. What am I missing?
I would recommend you to use those two services in the same docker-compose file and replace external_links with links
version: '3'
services:
mongodb:
image: mongo:latest
container_name: "mongodb"
volumes:
- ./data/db:/data/db
ports:
- 27017:27017
webapp:
build:
context: .
links:
- mongodb
depends_on:
- mongodb
ports:
- 8080:8080
How could I ensure mongodb is up and running before webapp is started?
AFAIK, the links will take care of the the situation.
or
You could use depends_on
Solved. Hosts were not accessible because they were in different networks. Creating a network (https://docs.docker.com/compose/networking/) and running both services in that network solved the problem.

Mongo service with specific port exposed in a bridge network docker

I have a sample app which consists of three parts:
mongo database
node api (server side)
angular web app (client side)
the goal is to containerize those three parts and run the app.
so to reach there I've created docker-compose.yml file like below:
# docker-compose -f docker-compose.prod.yml build
# docker-compose -f docker-compose.prod.yml up -d
# docker-compose -f docker-compose.prod.yml down
version: '3'
services:
mongodb:
image: mongo
container_name: mongodb-instance-microservices
ports:
- "27020:27017"
networks:
- microservices-network
client:
container_name: client-instance-microservices
image: client-microservices
build:
context: ./client
dockerfile: prod.dockerfile
ports:
- "8080:80"
- "443:443"
depends_on:
- api
networks:
- microservices-network
api:
container_name: api-instance-microservices
image: api-microservices
build:
context: ./server
dockerfile: server.dockerfile
environment:
- NODE_ENV=production
ports:
- "3000:3000"
depends_on:
- mongodb
networks:
- microservices-network
networks:
microservices-network:
driver: bridge
in the server side i am running the main app.js which is trying to connect to the mongodb using this connection string:
mongodb://mongodb-instance-microservices:27020/TestDatabase
the problem is the server can not connect to the mongo db container.
i tried to expose the default port for mongo like below:
mongodb:
image: mongo
container_name: mongodb-instance-microservices
ports:
- "27017:27017"
networks:
- microservices-network
and update the connection string in the app.js file like this:
mongodb://mongodb-instance-microservices:27017/TestDatabase
and it's work fine.
the question is how to expose different port for mongo container and make it work fine?
When you connect between services using a Docker-internal network, you always connect to the internal port of the service. You don't explicitly need to publish ports (in Compose, with a ports: directive); if you do, the port you'd connect to is the one on the right.
Style-wise, also note that you don't need to manually declare a private network with default options that will only be used within this Docker Compose file (Compose will do something very similar to that for you), and you don't need to declare container_name: just for inter-container connectivity (Compose will add a network alias that matches the name of the service).

Docker-compose networking, access host port from container

This is my compose file:
version: '3'
services:
web:
container_name: dash
build:
context: .
dockerfile: Dockerfile
args:
webpackVersion: 2.2.1
nodeVersion: "6.x"
ports:
- "3036:3036"
links:
- mongodb:dbhost
depends_on:
- mongodb
mongodb:
container_name: mongodb
build:
context: .
dockerfile: Dockerfile-mongodb
Right now web has access to mongodb container where I keep app configs. But I also need to be able access port 3306 on my local machine where I'm running docker-compose, from web.
I tried to follow the documentation, but I'm new in docker so it looks pretty complicated for me, how to use networking in docker-compose.
If any one can help me to understand this I'll be really grateful!
I found only one way to open all host ports, is to use network_mode: host
it should be also possible by using network but in my case first solution was enough.
version: '3'
services:
web:
container_name: dash
network_mode: host
build:
context: .
dockerfile: Dockerfile
args:
webpackVersion: 2.2.1
nodeVersion: "6.x"
ports:
- "3036:3036"
links:
- mongodb:dbhost
depends_on:
- mongodb
mongodb:
container_name: mongodb
network_mode: host
build:
context: .
dockerfile: Dockerfile-mongodb
network_mode: host won't work on mac, you should run docker in VB

Resources