mysql - NodeJS和Sequelize在docker compose中无法连接到MySQL

标签 mysql node.js docker docker-compose sequelize.js

我有一个非常相似的问题出现在这里:
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/

相关文章:

node.js - 如何在 expressjs 中使用 director 作为路由器

node.js - Angular 不显示创建的对象,直到我刷新页面

python - docker python :3 with docker-compose 中缺少环境变量

mysql - 如何避免所有存在重复的记录并仅获取唯一记录?

c# - Linq 与数据集。全部存储在内存中还是分页查询?

mysql - 需要对地址表建议进行标准化

mysql - sequelize - 如何添加额外的字段

Docker 网络 : Auto-discovering host names in a bridge network

java - 如何使用Java程序在Windows中运行Docker命令?

sql - 在 Windows 上使用 mysqldump