skip to Main Content

First of all, I tried my best through other stackoverflow posts and Googling, but the same error keeps occurring.

docker run --rm  --name mysql-container -e MYSQL_ROOT_PASSWORD=password -d -p 3305:3306 mysql:latest

First, if I run the mysql container with the above command, it runs normally.

CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                               NAMES
5980ecc42a28   mysql:latest   "docker-entrypoint.s…"   36 seconds ago   Up 35 seconds   33060/tcp, 0.0.0.0:3305->3306/tcp   mysql-container
  • Dockerfile
FROM node

WORKDIR /app

COPY package.json .

RUN npm install 

COPY . .

EXPOSE 80

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

After that, if I create a Dockerfile like this and build it, it builds normally.

docker build -t goals-node .   

After that, when I try to run the image I built, the ‘ENOTFOUND’ error continues to occur.

– app.js

const fs = require("fs");
const path = require("path");

const express = require("express");
const Sequelize = require("sequelize");
const bodyParser = require("body-parser");
const morgan = require("morgan");
const dotenv = require("dotenv");

dotenv.config({ path: "./env/mysql.env" });

const Goal = require("./models/goal");

const app = express();

const sequelize = new Sequelize(
  process.env.MYSQL_DATABASE,
  process.env.MYSQL_USER,
  process.env.MYSQL_ROOT_PASSWORD,
  {
    port: process.env.MYSQL_PORT,
    host: "mysql",
    dialect: "mysql",
    logging: false,
    pool: {
      max: 5,
      min: 0,
      acquire: 30000,
      idle: 10000,
    },
  }
);

– env/mysql.env

MYSQL_DATABASE=docker_test
MYSQL_ROOT_PASSWORD=itspassword // its not real password
MYSQL_PASSWORD=itspassword
MYSQL_DATA_DIR=./mysql_data
MYSQL_USER=root
MYSQL_PORT=3305

– error

myComputer@myComputer-MacBookPro backend % docker run --name goals-backend --rm  goals-node
80 port is ready
HostNotFoundError [SequelizeHostNotFoundError]: getaddrinfo ENOTFOUND mysql
    at ConnectionManager.connect (/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:96:17)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ConnectionManager._connect (/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:222:24)
    at async /app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:174:32
    at async ConnectionManager.getConnection (/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:197:7)
    at async /app/node_modules/sequelize/lib/sequelize.js:305:26
    at async Sequelize.authenticate (/app/node_modules/sequelize/lib/sequelize.js:457:5)
  parent: Error: getaddrinfo ENOTFOUND mysql
      at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:118:26) {
    errno: -3008,
    code: 'ENOTFOUND',
    syscall: 'getaddrinfo',
    hostname: 'mysql',
    fatal: true
  },
  original: Error: getaddrinfo ENOTFOUND mysql
      at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:118:26) {
    errno: -3008,
    code: 'ENOTFOUND',
    syscall: 'getaddrinfo',
    hostname: 'mysql',
    fatal: true
  }
}
  • package.json
{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "errorTest",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "dotenv": "^16.3.2",
    "morgan": "^1.10.0",
    "mysql2": "^3.7.1",
    "sequelize": "^6.35.2",
    "sequelize-cli": "^6.6.2"
  }
}

– goal.js

const Sequelize = require("sequelize");

module.exports = class Goal extends Sequelize.Model {
  static init(sequelize) {
    return super.init(
      {
        text: {
          type: Sequelize.STRING,
        },
      },
      {
        sequelize,
        modelName: "Goals",
        tableName: "goals",
      }
    );
  }
  static associate(db) {}
};

I looked through other articles and changed the settings for equalization in app.js, but the same error continues to occur. What’s the problem?

please help…

I’ve tried Googling and searching gpt, but the same problem occurs.

2

Answers


  1. The reason that you’re getting the ENOTFOUND error is that your two Docker containers are effectively sitting on different networks.

    The quickest (but not best) way to get this simply working would be to launch them both using the host’s network. The setup below should get everything working, which is always a good place to start. You can then tweak bits and pieces until it all does what you need.

    Launch your database like this:

    docker run --rm --name mysql-container 
      --net=host 
      -e MYSQL_ROOT_PASSWORD=password 
      -d 
      mysql:latest
    

    That will launch the MySQL container. Since it’s on the host network the database will be accessible on port 3306.

    Update the environment file:

    MYSQL_DATABASE=mysql
    MYSQL_ROOT_PASSWORD=password
    MYSQL_PASSWORD=password
    MYSQL_DATA_DIR=./mysql_data
    MYSQL_USER=root
    MYSQL_PORT=3306
    

    We’re using the (default) mysql database. When you create another database on the server you can specify that here. Have also changed the port to 3306.

    Here’s the updated app:

    const fs = require("fs");
    const path = require("path");
    
    const express = require("express");
    const Sequelize = require("sequelize");
    const bodyParser = require("body-parser");
    const morgan = require("morgan");
    const dotenv = require("dotenv");
    
    dotenv.config({ path: "./env/mysql.env" });
    
    // const Goal = require("./models/goal");
    
    const app = express();
    
    const sequelize = new Sequelize(
      process.env.MYSQL_DATABASE,
      process.env.MYSQL_USER,
      process.env.MYSQL_ROOT_PASSWORD,
      {
        port: process.env.MYSQL_PORT,
        host: "127.0.0.1",
        dialect: "mysql",
        logging: false,
        pool: {
          max: 5,
          min: 0,
          acquire: 30000,
          idle: 10000,
        },
      }
    );
    sequelize.authenticate();
    

    I’ve updated the host to "127.0.0.1" so that it connects to localhost (which is what we want because we’re using host networking).

    I added a package.json with the required packages.

    {
      "name": "test",
      "version": "1.0.0",
      "dependencies": {
              "dotenv": "*",
              "express": "*",
              "morgan": "*",
              "mysql2": "*",
              "sequelize": "*"
      },
      "devDependencies": {
      },
      "main": "n/a",
      "scripts": {
      }
    }
    

    The build and run.

    docker build -t goals-node . 
    docker run --net=host --name goals-backend --rm  goals-node
    

    This container is also run using host networking, so it’s able to connect to the MySQL container.

    If you want to create a new database (that is, not use the default database) then you’d need to specify the name of the database when you launch the MySQL container and update the environment file.

    docker run --rm --name mysql-container 
      --net=host 
      -e MYSQL_ROOT_PASSWORD=password 
      -e MYSQL_DATABASE=test 
      -d 
      mysql:latest
    
    MYSQL_DATABASE=test
    MYSQL_ROOT_PASSWORD=password
    MYSQL_PASSWORD=password
    MYSQL_DATA_DIR=./mysql_data
    MYSQL_USER=root
    MYSQL_PORT=3306
    

    🚨 Once you have this working I’d suggest that your next step would be to use Docker Compose. This is a more robust way to handle communication between multiple containers.

    Hope this helps. Feel free to post comments or questions and I’ll update accordingly.

    Login or Signup to reply.
  2. If you’re using plain Docker and not Compose, there are three things you need to do to make the containers connect to each other.

    The first is to create a Docker network. For historical reasons, plain docker run uses a legacy networking mode where containers can’t reach each other without special setup. You do not need any non-default options, you just need to create the network with some name.

    docker network create some-network
    

    When you run the two containers, you need to run them both on the same network.

    docker run -d 
      --name mysql-container 
      --net some-network      # <--
      ...
      mysql:latest
    docker run -d 
      --name goals 
      --net some-network      # <--
      ...
      goals-node
    

    Finally, when you make the connection between containers, use the server’s container name as a host name. I’d recommend making the database host name configurable the same way the other settings are.

    const sequelize = new Sequelize(
      ...,
      {
        host: process.env.MYSQL_HOST,
        ...
      }
    );
    
    MYSQL_HOST=mysql-container
    MYSQL_PORT=3306
    

    You use a docker run -p 3305:3306 option to remap the database port to a different host port. Connections between containers don’t use (or require) these mappings, so I’ve also changed MYSQL_PORT back to the default MySQL port 3306. If you’re not going to access the database from outside this container (including using things like the mysql CLI from the host) then it’s safe to delete the -p option entirely.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search