Aphorism44
Aphorism44

Reputation: 87

Bolt connection, Docker Compose + Neo4j + Node

I'm new to Docker Compose, and I'm trying to get two images (one a Node app, the other a Neo4j db) to work together locally. My OS is Ubuntu. While each image works fine separately, I can't get the Node app image to connect to the database image.

I'm almost certain is has to do with the port connections; to be precise, with the URL parameter I'm using in the driver connection:


    var driver = neo4j.driver("bolt://neo4j:7687", neo4j.auth.basic("tester", "tester"));

Where the "7687" is Neo4j's Bolt port to in the docker-compose.yml, and "neo4j" is the name I assigned to the Neo4j image (see below).

I was following (using a different JS driver) the only Node+Neo4j+Docker tutorial I could find (https://medium.com/@slavahatnuke/neo4j-node-js-docker-docker-compose-fdc1cc9cf405), and the user comments there seem to confirm that the error is in my connection URL.

To try and summarize:

  1. The Node app is using the official neo4j-javascript-driver to connect, via Bolt, to the Neo4j database. The exact code is:

    "use strict";

    var express = require('express');
    var neo4j = require('neo4j-driver').v1;
    const PORT = 8080;

    var app = express();

    //below is a test of the Neo4j connection, with which I have trouble connecting from in a Docker container

    router.get('/test', function (req, res) {
        var driver = neo4j.driver("bolt://neo4j:7687", neo4j.auth.basic("tester", "tester"));

        var session = driver.session();
        console.log(session);
        var countPromise = session.readTransaction(function(transaction) {
        var result = transaction.run("MATCH (n) RETURN COUNT(n) AS c")
            .then(function(result) {
                console.log(result);
                return result.records[0].get("c");
            });
            return result;
        });
        countPromise.then(function(result) {
            res.json(result);
            session.close();
            driver.close();
        });

    });


    app.listen(PORT);
    console.log("Running on " + PORT);

    module.exports = app;

  1. The Neo4j image is Docker's official Neo4j image.

  2. I am using the following docker-compose.yml file:

nodeapp:
  image: node:latest
  volumes:
   - ./nodeapp:/nodeapp
  links:
   - neo4j
  ports:
   - "18080:8080"
  working_dir: /nodeapp
  entrypoint: node index.js

neo4j:
  image: neo4j
  ports:
   - "17474:7474"
   - "17687:7687"
  volumes:
  - ./db/dbms:/data/dbms
  1. When I run it (with "docker-compose up"), I can:

    A. Access the Neo4j browser console fine, by pointing my browser to: "localhost:17474". I used the provided user credentials to sign in and can run Cypher queries fine.

    B. If I don't try to create a Neo4j driver, I can run any regular GET function in the Node by pointing my browser to: "localhost:18080".

    C. The output indicates the following: "Bolt enabled on 0.0.0.0:7687."

So I've been concentrating on the connection URL within the Node.

But it has not connected yet.Specifically, according to the log, the program just keeps trying and failing to create the driver (it keeps repeating the line "This is a Neo4j connection test").

I'm certain there's something simple to Docker Compose that I'm missing.

Without Docker, I used the URL "bolt://localhost:7687" to successfully connect the app to the database. Now that it's in Docker, I don't know what I should use.

Thank you for any guidance.

UPDATE:

I'm afraid none of these suggestions have worked.

Here is some more information:

  1. When I run "docker-compose ps", I get this, so it seems like the ports are mapped properly.
      Name             Command             State              Ports       
-------------------------------------------------------------------------
initialnode_neo4   /docker-           Up                 7473/tcp, 0.0.0. 
j_1                entrypoint.sh                         0:17474->7474/tc 
                   neo4j                                 p, 0.0.0.0:17687 
                                                         ->7687/tcp       
initialnode_node   node index.js      Up                 0.0.0.0:18080->8 
app_1                                                    080/tcp  
  1. I inspected the Neo4j image when running, and here are some of the relevant results:

     "NetworkMode": "default",
                "PortBindings": {
                    "7474/tcp": [
                        {
                            "HostIp": "",
                            "HostPort": "17474"
                        }
                    ],
                    "7687/tcp": [
                        {
                            "HostIp": "",
                            "HostPort": "17687"
                        }
                    ]
                },

    ...
    "ExposedPorts": {
                    "7473/tcp": {},
                    "7474/tcp": {},
                    "7687/tcp": {}
                },
    ...
    "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "5eb2b7805cc802391c08be8c85cdbb19fd42de6cc794e76e57f5214c6763c140",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {
                    "7473/tcp": null,
                    "7474/tcp": [
                        {
                            "HostIp": "0.0.0.0",
                            "HostPort": "17474"
                        }
                    ],
                    "7687/tcp": [
                        {
                            "HostIp": "0.0.0.0",
                            "HostPort": "17687"
                        }
                    ]
                },

    ...

    "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "8ffa640b707301bb9b8b6c2a1cfb6f5deac8c1a5f5de9e9de0976697b01027ef",
                        "EndpointID": "941911b65cf0b714fa13ac45ca967478a513fe5c282283aa0bfe20afcc0df06f",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02"
                    }
                }
            }
    ...

  1. I checked the log for the Neo4j issue, and I'm getting this all the time:

    {"log":"  _writeConnectionHolder: \n","stream":"stdout","time":"2017-05-05T16:20:59.37931736Z"}
    {"log":"   ConnectionHolder {\n","stream":"stdout","time":"2017-05-05T16:20:59.379324034Z"}
    {"log":"     _mode: 'WRITE',\n","stream":"stdout","time":"2017-05-05T16:20:59.379330305Z"}
    {"log":"     _connectionProvider: \n","stream":"stdout","time":"2017-05-05T16:20:59.379353139Z"}
    {"log":"      DirectConnectionProvider {\n","stream":"stdout","time":"2017-05-05T16:20:59.379363823Z"}
    {"log":"        _address: 'neo4j:7687',\n","stream":"stdout","time":"2017-05-05T16:20:59.3793706Z"}
    {"log":"        _connectionPool: [Object],\n","stream":"stdout","time":"2017-05-05T16:20:59.379377162Z"}
    {"log":"        _driverOnErrorCallback: [Function: bound _driverOnErrorCallback] },\n","stream":"stdout","time":"2017-05-05T16:20:59.379384507Z"}
    {"log":"     _referenceCount: 0,\n","stream":"stdout","time":"2017-05-05T16:20:59.379391793Z"}
    {"log":"     _connectionPromise: Promise { null } },\n","stream":"stdout","time":"2017-05-05T16:20:59.379398668Z"}
    {"log":"  _open: true,\n","stream":"stdout","time":"2017-05-05T16:20:59.379405771Z"}
    {"log":"  _hasTx: false,\n","stream":"stdout","time":"2017-05-05T16:20:59.379412739Z"}
    {"log":"  _lastBookmark: undefined,\n","stream":"stdout","time":"2017-05-05T16:20:59.379437046Z"}
    {"log":"  _transactionExecutor: \n","stream":"stdout","time":"2017-05-05T16:20:59.379445641Z"}
    {"log":"   TransactionExecutor {\n","stream":"stdout","time":"2017-05-05T16:20:59.379452547Z"}
    {"log":"     _maxRetryTimeMs: 30000,\n","stream":"stdout","time":"2017-05-05T16:20:59.379459251Z"}
    {"log":"     _initialRetryDelayMs: 1000,\n","stream":"stdout","time":"2017-05-05T16:20:59.379466191Z"}
    {"log":"     _multiplier: 2,\n","stream":"stdout","time":"2017-05-05T16:20:59.379472573Z"}
    {"log":"     _jitterFactor: 0.2,\n","stream":"stdout","time":"2017-05-05T16:20:59.379478888Z"}
    {"log":"     _inFlightTimeoutIds: [] } }\n","stream":"stdout","time":"2017-05-05T16:20:59.379485201Z"}
    {"log":"(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Connection was closed by server\n","stream":"stderr","time":"2017-05-05T16:21:32.301674097Z"}

I have a co-worker who was able to connect, but he had to use a sketchy third-party library, and he couldn't connect via Bolt, only 7474.

Upvotes: 2

Views: 2462

Answers (2)

Aphorism44
Aphorism44

Reputation: 87

It appears the issue was due to my personal computer settings, which explains why nobody else had problems with this.

I had a local version of Neo4j running, in addition to the Docker Neo4j image, and they were all using the same ports.

This caused the connection to be refused.

The solution in my case was to:

  1. Stop my local version of Neo4j (it is up automatically when I start my computer)
  2. Then run docker-compose using just about any of the suggested URLs (I'm using just "bolt:neo4j: since the Docker image automatically maps Bolt to 7687).

Upvotes: 1

tintin
tintin

Reputation: 171

try: var driver = neo4j.driver("bolt://neo4j:7687", neo4j.auth.basic("neo4j", "neo4j"));

The port should be 7687 and the login credentials the default unless you have changed these manually once the container is started.

One more thing, neo4j will take a few seconds to start-up so if you try to connect right away most likely the connection will fail.

Upvotes: 0

Related Questions