我有一个非常相似的问题出现在这里:
Node.js connect to MySQL Docker container ECONNREFUSED
但不幸的是,提议的解决方案不起作用。
我有一个带有 Typescript(可能不相关)、Sequelize 和 MySQL 数据库的 NodeJS 项目。
我已经设置了一个带有脚本的 docker-compose 文件,这些脚本基于 github 的脚本来设置它们并启动它们来统治它们。script/setup
只是为数据库创建卷并启动它:
...
docker-compose down
docker volume create --name=tournaments-data
docker-compose up -d tournaments-db
完成后,我运行
script/start
,它正在启动 Web 应用程序:...
docker-compose up web
version: '3'
volumes:
tournaments-data:
services:
base: &app_base
build:
context: .
dockerfile: Dockerfile
depends_on:
- tournaments-db
web:
<<: *app_base
command: npm run watch-debug
volumes:
- ./dist:/usr/src/app/dist
ports:
- 3000:3000
- 5858:5858
tournaments-db:
image: mysql:5.6.45
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'whatever'
MYSQL_DATABASE: tournaments
expose:
- '3307'
ports:
- '3307:3306'
volumes:
- tournaments-data:/var/lib/mysql
我的 Sequelize 配置如下所示:
...
development: {
username: 'root',
password: 'whatever',
database: 'tournaments',
host: 'tournaments-db',
port: '3307',
dialect: 'mysql',
operatorsAliases: false,
}
...
所有容器都正确启动,我能够使用以下命令从命令行成功地将 连接到 MySQL 容器:
mysql -uroot -p -h 127.0.0.1 -P 3307 --protocol=tcp
和 JetBrains Datagrip。看起来 NodeJS 应用程序似乎无法正确连接到 mysql 数据库,因为我收到以下错误:
Unable to connect to the database: ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306
我尝试从所有 IP(而不仅仅是 localhost)授予 root 访问权限,但这也不起作用。
还认为这是 docker-compose 的网络问题,所以我确认它们在同一个网络上(它们是),还尝试通过 docker-compose 为它们创建不同的网络,但这也不起作用。
有没有人有任何想法可能会丢失?由于我可以从外部连接到 mysql 实例,因此我认为我缺少一些配置或类似的配置,但是在查看了很多建议的解决方案后,没有用。
P.S 由于业务限制,MySQL 版本被锁定,所以我无法升级/使用其他版本
从 Sequelize 返回的完整错误消息:
web_1 | [Node] Unable to connect to the database: ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306
web_1 | [Node] at /usr/src/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:123:19
web_1 | [Node] at tryCatcher (/usr/src/app/node_modules/bluebird/js/release/util.js:16:23)
web_1 | [Node] at Promise._settlePromiseFromHandler (/usr/src/app/node_modules/bluebird/js/release/promise.js:547:31)
web_1 | [Node] at Promise._settlePromise (/usr/src/app/node_modules/bluebird/js/release/promise.js:604:18)
web_1 | [Node] at Promise._settlePromise0 (/usr/src/app/node_modules/bluebird/js/release/promise.js:649:10)
web_1 | [Node] at Promise._settlePromises (/usr/src/app/node_modules/bluebird/js/release/promise.js:725:18)
web_1 | [Node] at _drainQueueStep (/usr/src/app/node_modules/bluebird/js/release/async.js:93:12)
web_1 | [Node] at _drainQueue (/usr/src/app/node_modules/bluebird/js/release/async.js:86:9)
web_1 | [Node] at Async._drainQueues (/usr/src/app/node_modules/bluebird/js/release/async.js:102:5)
web_1 | [Node] at Immediate._onImmediate (/usr/src/app/node_modules/bluebird/js/release/async.js:15:14)
web_1 | [Node] at processImmediate (internal/timers.js:439:21) {
web_1 | [Node] name: 'SequelizeConnectionRefusedError',
web_1 | [Node] parent: Error: connect ECONNREFUSED 127.0.0.1:3306
web_1 | [Node] at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1134:16) {
web_1 | [Node] errno: 'ECONNREFUSED',
web_1 | [Node] code: 'ECONNREFUSED',
web_1 | [Node] syscall: 'connect',
web_1 | [Node] address: '127.0.0.1',
web_1 | [Node] port: 3306,
web_1 | [Node] fatal: true
web_1 | [Node] },
web_1 | [Node] original: Error: connect ECONNREFUSED 127.0.0.1:3306
web_1 | [Node] at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1134:16) {
web_1 | [Node] errno: 'ECONNREFUSED',
web_1 | [Node] code: 'ECONNREFUSED',
web_1 | [Node] syscall: 'connect',
web_1 | [Node] address: '127.0.0.1',
web_1 | [Node] port: 3306,
web_1 | [Node] fatal: true
web_1 | [Node] }
web_1 | [Node] }
最佳答案
所以,我终于弄清楚出了什么问题。
我解决了一个问题,但导致了另一个问题。基本上我创建的 Sequelize 实例没有通过主机 + 端口配置,所以它使用了默认的 127.0.0.1:3306
本质上是这样的:
export const sequelize = new Sequelize({
database: config.database,
username: config.username,
password: config.password,
models: [path.join(__dirname, '/models')],
dialect: config.dialect,
});
取而代之的是:
export const sequelize = new Sequelize({
host: config.host,
port: config.port,
database: config.database,
username: config.username,
password: config.password,
models: [path.join(__dirname, '/models')],
dialect: config.dialect,
});
So config was correct, but I was just not using it properly in my code.
关于mysql - NodeJS和Sequelize在docker compose中无法连接到MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60318631/