skip to Main Content

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
}

2

Answers


  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

    Login or Signup to reply.
  2. 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"
    });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search