0

I have created a NodeJS backend server which is connected to MySQL. By using Dockers, I created an image with the following commands to run my nodeJS and package.json file (which includes MySQL). The following is my Dockerfile:

FROM node

WORKDIR /app

COPY package.json .

RUN npm install

COPY . /app

EXPOSE 3000

CMD ["node", "app.js"]

I have another file to create the connection with MySQL using NodeJS:

const mysql = require("mysql");

const con = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "ilovestackoverflow",
  database: "db830",
  port: "3306"
});

con.connect(function (err, rows) {
  if (err) throw err;
  console.log("Database is connected!");
});

module.exports = con;

I tried to run Dockers (docker run -p 3000:3000 help:help) but I face the following error (not sure how to solve it, please help!! ):

Server is listening on Port: 3000
/app/config/database.js:12
  if (err) throw err;
           ^

Error: connect ECONNREFUSED 127.0.0.1:3306
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1247:16)
    --------------------
    at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Protocol.handshake (/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
    at Connection.connect (/app/node_modules/mysql/lib/Connection.js:116:18)
    at Object.<anonymous> (/app/config/database.js:11:5)
    at Module._compile (node:internal/modules/cjs/loader:1120:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1174:10)
    at Module.load (node:internal/modules/cjs/loader:998:32)
    at Module._load (node:internal/modules/cjs/loader:839:12)
    at Module.require (node:internal/modules/cjs/loader:1022:19)
    at require (node:internal/modules/cjs/helpers:102:18) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 3306,
  fatal: true
}
Jessica
  • 243
  • 1
  • 10

2 Answers2

0

In a multi-container environment you have multiple networks in docker containers, witch each container having its own network namespace. Networking in Docker when you need to access other docker containers is done via the name of the service. In a docker-compose setup you would reference the name of the service. While using plain docker containers, it is a bit harder. You need to

  1. Create a docker network

docker network create awesomeNetwork

  1. Join the first container into the network

docker network connect nodebackend awesomeNetwork

  1. Join the second container into the network

docker network connect db awesomeNetwork

Now you can reference another container inside the container network using the name db/nodebackend respectively.


In a dev/local docker-compose environment, I highly suggest using docker-compose and writing your compose manifest. Then you would need not to create the network as it would be created for you everytime. The setup would look like this

# docker-compose.yml
version: '3.8'
services:
  nodeBackend:
    build: .
    context: ./Path
    dockerfile: Dockerfile
    ports:
     - "3000:3000"
  db:
    image: mysql
    ports:
      - 3306:3306
    volumes:
      - <path>:/var/lib/mysql      # select a path to persist your data
    environment:
      - MYSQL_ROOT_PASSWORD=<password_root>
      - MYSQL_PASSWORD=<password>
      - MYSQL_USER=<user>
      - MYSQL_DATABASE=<mysql_db_name>

Now you can connect to db in node application using the hostname db

const con = mysql.createConnection({
  host: "db",
  user: "root",
  password: "ilovestackoverflow",
  database: "db830",
  port: "3306"
});

Pavol Krajkovič
  • 505
  • 1
  • 12
  • So both containers "nodebackend" and "db" belong to the same image of "mysql"? – Jessica Aug 18 '22 at 08:50
  • No you need to have two docker containers, one for the backend and the second one for the database – Pavol Krajkovič Aug 18 '22 at 08:53
  • I have created both "nodebackend" and "db" containers in the same image, which container should I run? – Jessica Aug 18 '22 at 08:54
  • container is the instance of the image, whereas image is a blueprint for the container. You cannot have two containers inside image as it does not make sense. You need to have two containers each running one image. For the first container, you would be using the image of the database. For the second container, you would be using the image of the dockerfile you provided – Pavol Krajkovič Aug 18 '22 at 08:59
  • If you mean to say that, you have on your local machine a mysql database, then you need to connect the container to your host network. – Pavol Krajkovič Aug 18 '22 at 09:00
  • Ahh I see, how do I execute my network with the 2 containers? – Jessica Aug 18 '22 at 09:02
  • I have edited the compose file in my answer, please check it out. The ```db``` should be what you are looking for, add the correcnt env variables and path to persist your data. Now for the node application i suggest you look at this link if you have not published your node image. https://stackoverflow.com/questions/65622477/what-is-context-in-docker-compose – Pavol Krajkovič Aug 18 '22 at 09:08
-1

You are exposing port 3000 in docker container but trying to listen on port 3306 so.. I think you need to set EXPOSE 3306 in your dockerfile

KubePony
  • 144
  • 1
  • 7