How to connect Node.js app to database when they a

2019-01-12 11:31发布

问题:

I have these containers running:

I am able to visit node app at localhost:49160 and database at localhost:7474 as expected.

However, the node app can't seem to actually connect to the database. I get this error when I try:

Error: connect ECONNREFUSED 127.0.0.1:7474
    at Object.exports._errnoException (util.js:1018:11)
    at exports._exceptionWithHostPort (util.js:1041:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)

This normally means it can't find the database at that host:port.

Again, I am able to visit 127.0.0.1:7474 and clearly see the database is running.

I have also tried to connecting to 0.0.0.0:7474, but that didn't work either.

There are no issues when I run the node app locally + database in docker container, but this problem occurs when I also run the node app in a docker container.

What host and port should be database be available at (what should I connect to?), and what am I probably missing or doing wrong?

Dockerfile for node-app

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN yarn

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "yarn", "start" ]

docker neo4j run cmd

docker run -d -e NEO4J_AUTH=none \
    --publish=7474:7474 --publish=7687:7687 \
    --volume=$HOME/neo4j/data:/data \
    --volume=$HOME/neo4j/logs:/logs \
    --volume=$HOME/neo4j/conf:/conf \
    --volume=$HOME/neo4j/plugins:/plugins \
    neo4j:3.1.4

回答1:

I am describing one way of doing it, and there might be other possible ways which I am currently unaware of. Since the links are deprecated now, we can use networks to connect one container to another.

First of all we create a network with this command:

docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw

And then we connect the mysql container by assigning it an IP address from the network we created. And yeah, we specify the network too. This command does the required purpose:

docker run -itd --rm \
  --network=isolated_nw \
  --ip=172.25.3.3 \
  --name=mysql \
  --volume "$(pwd)/database/:/docker-entrypoint-initdb.d" mysql

Now we have got our mysql container running and connected to the isolated_nw we created. Its time to get our other container connected to the same network and access the mysql container. Adding --network=isolated_nw flag while running a container adds the container to the network. And we shall use this flag while running our other container which requires to access mysql.

Now it is done! Inside this other container we can access mysql container at the IP address we allocated, i.e, at 172.25.3.3. An implementation of these things can be seen here.



回答2:

(I cannot use comments yet, so reaching you this way. Will update if it works)

Shouldn't you link the containers to expose them? Docker v17.06 docs state:

If the operator uses --link when starting a new client container in the default bridge network, then the client container can access the exposed port via a private networking interface. If --link is used when starting a container in a user-defined network as described in Docker network overview, it will provide a named alias for the container being linked to.

I also found this useful (brought me to the docs): https://www.digitalocean.com/community/tutorials/how-to-deploy-a-node-js-and-mongodb-application-with-rancher-on-ubuntu-14-04

(You could take a look at Rancher after reading. Rocks for Docker)