Docker与Sequelize连接持续出现ENOTFOUND错误求助
问题:Node容器无法连接MySQL容器,出现ENOTFOUND错误
我查过Stack Overflow帖子和谷歌搜索,还是一直碰到相同错误。
操作过程
- 启动MySQL容器,运行正常:
docker run --rm --name mysql-container -e MYSQL_ROOT_PASSWORD=password -d -p 3305:3306 mysql:latest
容器状态:
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构建Node镜像,构建过程无问题:
FROM node WORKDIR /app COPY package.json . RUN npm install COPY . . EXPOSE 80 CMD [ "node", "app.js" ]
构建命令:
docker build -t goals-node .
- 运行Node镜像时,持续出现ENOTFOUND错误。
相关配置
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
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) {} };
错误信息
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 } }
我试过调整app.js里的Sequelize配置,但错误还是一直出现,问题出在哪?
解决方案
问题出在三个核心点:容器网络隔离、端口配置错误、密码不匹配。
1. 容器网络隔离问题
默认情况下,Docker容器处于独立的网络命名空间,Node容器无法通过mysql主机名解析到MySQL容器,必须将两个容器放到同一个Docker网络中。
解决步骤(推荐自定义网络)
- 创建自定义网络:
docker network create goals-network
- 重新启动MySQL容器,加入该网络,同时指定自动创建目标数据库(避免后续数据库不存在的错误):
docker run --rm --name mysql-container --network goals-network -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=docker_test -d -p 3305:3306 mysql:latest
- 运行Node容器时加入同一个网络:
docker run --name goals-backend --rm --network goals-network goals-node
2. 端口配置错误
容器之间通信使用的是容器内部端口,而非主机映射端口。MySQL容器内部端口为3306,你在env/mysql.env里配置的MYSQL_PORT=3305是主机映射端口,需要修改为:
MYSQL_PORT=3306
3. 密码不匹配
你启动MySQL容器时设置的MYSQL_ROOT_PASSWORD=password,与env/mysql.env里的MYSQL_ROOT_PASSWORD=itspassword不一致。要么修改MySQL启动命令的密码为itspassword,要么把env里的密码改成password。
完成以上修改后,Node容器即可正常连接到MySQL容器。
内容的提问来源于stack exchange,提问作者brgndy
相关产品推荐
相关产品推荐

