【问题标题】:Solved - NodeJS Docker container can't connect to MySQL (on host)已解决 - NodeJS Docker 容器无法连接到 MySQL(在主机上)
【发布时间】:2021-11-09 11:41:57
【问题描述】:

Ubuntu 20.04.3 LTSDocker 20.10.8MySQL 8.0.26(安装在主机上)。
我有一个 nodejs 试图 mysql.createPool({host: 'host.docker.internal', ...}) 但我得到了

错误:连接 ECONNREFUSED 127.0.0.1:3306
在 TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)
在 Protocol._enqueue (.../node_modules/mysql/lib/protocol/Protocol.js:144:48)
在 Protocol.handshake (.../node_modules/mysql/lib/protocol/Protocol.js:51:23)
在 PoolConection.connect (.../node_modules/mysql/lib/Connection.js:116:18)
在 Pool.getConnection (.../node_modules/mysql/lib/Pool.js:48:16)

我检查了docker exec -it ... ping host.docker.internal 确实被解析为 172.17.0.1。
我能够使用host.docker.internal 访问同一主机上的另一个容器。我相信这证明我已经正确运行了--add-host=host.docker.internal:host-gateway

我还可以通过在 localhost127.0.0.1 上使用 node xyz.js 独立运行 js 来查询 MySQL。

然后我做了一个疯狂的实验,通过在主机上运行 js 独立 node xyz.jsmysql.createPool({host: '172.17.0.1', ...}) 它会给出

连接 ECONNREFUSED 172.17.0.1:3306`

但是如果我编辑/etc/hosts并添加172.17.0.1 host.docker.internal(在主机上)和mysql.createPool({host: 'host.docker.internal', ...}),js可以独立连接到MySQL!

****************************** 已解决 ***************** *********
docker forum 得到提示,原来我缺少的是允许外部 IP 访问 MySQL。这就是我所做的:

  1. /etc/mysql/mysql.conf.d/下,mysql.cnf为空白文件; mysqld.cnfbind-addressmysqlx-bind-address 两者 = 127.0.0.1,我只将 bind-address 更改为 127.0.0.1,host.docker.internal 然后 systemctl restart mysql
  2. /etc/hosts之前添加了一个条目172.17.0.1 host.docker.internal
  3. CREATE USER 'reader'@'%' IDENTIFIED WITH mysql_native_password BY 'xxxxx'

【问题讨论】:

  • 您能添加您的docker-compose 或您的运行命令吗?
  • 嗨 Joseph,我使用的是 docker run 命令以及 -p 80:5050 --name --restart 和 --add-host 参数。 (5050 是 J 正在监听的容器化端口)

标签: mysql node.js docker ubuntu-20.04


【解决方案1】:

如果你使用 127.0.0.1,那么容器会尝试在容器内的 localhost 上连接,但 mysql 正在 docker 主机上运行。

你可以尝试在docker添加的网络接口上连接它,你可以使用命令ip a检查,请看下面的输出

4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:53:81:5c:57 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

在我的情况下,我会使用下面的 url 连接到 mysql:

172.17.0.1:3306

【讨论】:

  • 但他提到他应该使用host.docker.internal,并且它适用于另一个容器,你确定这不会改变你的答案吗?
  • 不幸的是,我也尝试了 172.17.0.1 但没有奏效。这让我想知道,host.docker.internal 是如何被转换为 127.0.0.1 并最终出现该错误的
  • 输入命令“ip a”时是否列出了相同的内部 ip (172.17.0.1)?
  • 嗨 @AshishRanjan ,记录一下,是的,我的 docker0 网关也是 172.17.0.1
  • 我做的一件疯狂的事情是运行 js 独立 node xyz.jsmysql.createPool({host: '172.17.0.1', ...}) 与成功的 localhost/127.0.0.1 不同,它返回 ECONNREFUSED 错误 但是 当我(在主机上)编辑/etc/hosts 并添加172.17.0.1 host.docker.internalnode xyz.jsmysql.createPool({host: 'host.docker.internal', ...}) 时,独立的js 工作!怎么回事?!
【解决方案2】:

我正在运行一个 docker-compose NodeJS 应用程序,该应用程序在端口 3306 上连接到 Linux 主机 MySQL 数据库。要解决所描述的错误:

  • 专门针对Ubuntu 20.04.3 LTS & mysql Ver 15.1 Distrib 10.3.32-MariaDB,配置见/etc/mysql/mariadb.conf.d/50-server.cnf

    • 如果你不确定配置在哪里,运行以下命令来定位:

       grep -rnw 'bind-address' /etc/mysql/
      
  • 继续编辑 mysql 服务器配置,将 127.0.0.1 替换为 0.0.0.0,如 Docker 论坛 here 中所述。

sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf
  • 进行以下更改:

     - bind-address            = 127.0.0.1
     + bind-address            = 0.0.0.0
    
  • 并重启 mysql (MariaDB)

sudo systemctl restart mariadb.service

在运行 docker-compose 时,之前失败的容器现在可以访问本地 SQL 数据库了!

【讨论】:

    猜你喜欢
    • 2020-10-20
    • 2023-03-21
    • 2017-08-10
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    相关资源
    最近更新 更多