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
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:
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:
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:
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.The build and run.
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.
🚨 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.
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.When you run the two containers, you need to run them both on the same network.
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.
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 changedMYSQL_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 themysql
CLI from the host) then it’s safe to delete the-p
option entirely.