Cannot access Neo4j container with Neomodel

185 Views Asked by At

I have 2 different containers running with docker-compose. Here is my docker-compose.yml:

version: '3'

services:
    #Create backend container
    backend:
        build: ./backend # path to Dockerfile
        ports: # Port binding to host from docker container
            - "5000:5000"
        container_name: buzzworks-backend
        volumes: 
            - ${PWD}/backend:/app
        depends_on: 
            - db
        environment: 
            FLASK_APP: flaskr
            FLASK_ENV: development
            NEO_USER: ${NEO_USER}
            NEO_PW: ${NEO_PW}
    
    db:
        image: neo4j:4.1.1
        container_name: buzzworks-neo4j
        ports:
            - "7474:7474"
            - "7687:7687"
        volumes:
            - ${HOME}/neo4j/data:/data
            - ${HOME}/neo4j/logs:/logs
            - ${HOME}/neo4j/import:/var/lib/neo4j/import
            - ${HOME}/neo4j/plugins:/plugins
        environment:
            NEO4J_AUTH: ${NEO_USER}/${NEO_PW}
            NEO4J_dbms_logs_debug_level: ${NEO_DEBUG_LEVEL}

The corresponding network it generates looks right to me:

    {
        "Name": "buzzworksai_default",
        "Id": "db4efc0286a9464cadde13cf1306f241b7a353295904b15b163e761289ba9d3f",
        "Created": "2020-08-27T11:23:15.925483629-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "640650c163f746e480bf677abdeaf8edf6483b7dac2a260c2e3b3bc3319dffef": {
                "Name": "buzzworks-neo4j",
                "EndpointID": "ddbad1a179cc51655a779b07c91d6d949b0612bf985abc9c45e1794b35f4a565",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "ba47173d1dbc31e4e416eaf30d2314e6d2a20a36b389cb76cd1edcbea489184e": {
                "Name": "buzzworks-backend",
                "EndpointID": "17ff278f3db5ad609be682cdf912ca755587e07ef08d6023bf3ecb33a6c4bc31",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "buzzworksai",
            "com.docker.compose.version": "1.26.2"
        }
    }
]

I can access the web interface of the neo4j database just fine. The problem occurs when I am trying to connect to the database with neomodel. I have tried running neomodel_remove_labels --db bolt://<user>:<password>@db:7687 with the appropriate credentials from the shell of the python container. I get this error:

Traceback (most recent call last):
  File "/usr/local/bin/neomodel_remove_labels", line 35, in <module>
    main()
  File "/usr/local/bin/neomodel_remove_labels", line 30, in main
    db.set_connection(bolt_url)
  File "/usr/local/lib/python3.8/dist-packages/neomodel/util.py", line 93, in set_connection
    self.driver = GraphDatabase.driver(u.scheme + '://' + hostname,
  File "/usr/local/lib/python3.8/dist-packages/neo4j/__init__.py", line 108, in driver
    return Driver(uri, **config)
  File "/usr/local/lib/python3.8/dist-packages/neo4j/__init__.py", line 147, in __new__
    return subclass(uri, **config)
  File "/usr/local/lib/python3.8/dist-packages/neo4j/__init__.py", line 221, in __new__
    pool.release(pool.acquire())
  File "/usr/local/lib/python3.8/dist-packages/neobolt/direct.py", line 715, in acquire
    return self.acquire_direct(self.address)
  File "/usr/local/lib/python3.8/dist-packages/neobolt/direct.py", line 608, in acquire_direct
    connection = self.connector(address, error_handler=self.connection_error_handler)
  File "/usr/local/lib/python3.8/dist-packages/neo4j/__init__.py", line 218, in connector
    return connect(address, **dict(config, **kwargs))
  File "/usr/local/lib/python3.8/dist-packages/neobolt/direct.py", line 972, in connect
    raise last_error
  File "/usr/local/lib/python3.8/dist-packages/neobolt/direct.py", line 963, in connect
    s, der_encoded_server_certificate = _secure(s, host, security_plan.ssl_context, **config)
  File "/usr/local/lib/python3.8/dist-packages/neobolt/direct.py", line 854, in _secure
    s = ssl_context.wrap_socket(s, server_hostname=host if HAS_SNI and host else None)
  File "/usr/lib/python3.8/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/lib/python3.8/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
OSError: [Errno 0] Error

I have tried to access the container from my host with bolt://<user>:<password>@localhost:7687 but I still get the same error.

2

There are 2 best solutions below

1
On BEST ANSWER

I believe this may be your issue which is related to neo4j: https://github.com/neo4j/neo4j/issues/12392

The suggestion there is:

Neo4j 4.0 has encryption turned off by default. You need to explicitly turn encryption back on for Bolt server in server config file. Then you shall be able to connect using 1.7 python driver with default settings.

The following is an example of how you can turn encryption back on Bolt Server with private.key and public.crt in directory $neo4jHome/certificates/bolt.

dbms.connector.bolt.enabled=true

# allows both encrypted and unencrypted driver connections
dbms.connector.bolt.tls_level=OPTIONAL

dbms.ssl.policy.bolt.enabled=true
dbms.ssl.policy.bolt.base_directory=certificates/bolt
#dbms.ssl.policy.bolt.private_key=private.key
#dbms.ssl.policy.bolt.public_certificate=public.crt

You can choose any trusted key and certificate service to generate the private key and public certificate used here.

1
On

You need to set the network option on your docker-compose file. Please read this link and then you will understand it well.

You should do something like this:

version: '3'

services:
    #Create backend container
    backend:
        build: ./backend # path to Dockerfile
        ports: # Port binding to host from docker container
            - "5000:5000"
        container_name: buzzworks-backend
        volumes: 
            - ${PWD}/backend:/app
        depends_on: 
            - db
        environment: 
            FLASK_APP: flaskr
            FLASK_ENV: development
            NEO_USER: ${NEO_USER}
            NEO_PW: ${NEO_PW}
        networks:
            - mynetwork
    
    db:
        image: neo4j:4.1.1
        container_name: buzzworks-neo4j
        ports:
            - "7474:7474"
            - "7687:7687"
        volumes:
            - ${HOME}/neo4j/data:/data
            - ${HOME}/neo4j/logs:/logs
            - ${HOME}/neo4j/import:/var/lib/neo4j/import
            - ${HOME}/neo4j/plugins:/plugins
        environment:
            NEO4J_AUTH: ${NEO_USER}/${NEO_PW}
            NEO4J_dbms_logs_debug_level: ${NEO_DEBUG_LEVEL}
        networks:
            - mynetwork

networks:
    mynetwork: