Node.js 连接到 MySQL Docker 容器 ECONNREFUSED

Posted

技术标签:

【中文标题】Node.js 连接到 MySQL Docker 容器 ECONNREFUSED【英文标题】:Node.js connect to MySQL Docker container ECONNREFUSED 【发布时间】:2018-01-06 02:01:47 【问题描述】:

在您将此问题标记为重复之前,请注意我确实阅读了其他答案,但它并没有解决我的问题。

我有一个由两个服务组成的 Docker 组合文件:

version: "3"
services:
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_HOST: localhost
      MYSQL_DATABASE: mydb
      MYSQL_USER: mysql
      MYSQL_PASSWORD: 1234
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3307:3306"
    expose:
      - 3307
    volumes:
      - /var/lib/mysql
      - ./mysql/migrations:/docker-entrypoint-initdb.d
    restart: unless-stopped
  web:
    build:
      context: .
      dockerfile: web/Dockerfile
    volumes:
      - ./:/web
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: development
      PORT: 3000
    links:
      - mysql:mysql
    depends_on:
      - mysql
    expose:
      - 3000
    command: ["./wait-for-it.sh", "mysql:3307"]

/web/Dockerfile:

FROM node:6.11.1

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app/
RUN npm install

COPY . /usr/src/app

CMD [ "npm", "start" ]

docker-compose up --build 服务启动后,"wait-for-it.sh" 脚本在等待 mySQL 启动时超时(所以暂时我在测试数据库连接时没有使用它,我只是等到控制台显示 MySQL 是准备好接受传入的连接)

当 MySQL 从主机运行时,我可以使用 Sequel Pro 登录并查询数据库并从 ./mysql/migrations 获取示例记录

我也可以通过 SSH 连接到正在运行的 MySQL 容器并执行相同的操作。

但是,我的 Node.js 应用在连接时会生成 ECONNREFUSED 127.0.0.1:3307

MySQL 初始化:

import * as mysql from 'promise-mysql'

const config = 
    host: 'localhost',
    database: 'mydb',
    port: '3307',
    user: 'mysql',
    password: '1234',
    connectionLimit: 10


export let db = mysql.createPool(config);

MySQL 查询:

import  db  from '../db/client'

export let get = () => 

return db.query('SELECT * FROM users', [])
    .then((results) => 
        return results

    )
    .catch((e) => 
        return Promise.reject(e)
    )

点击url时调用路由/

import  Router  from 'express';
import * as repository from '../repository'
export let router = Router();

router.get('/', async (req, res) => 

    let users;

    try
        users = await repository.users.get();
     catch(e)
        // ECONNREFUSED 127.0.0.1:3307
    

    res.render('index', 
        users: users
    );
);

这不太可能是竞争条件,因为同时当 Node.js 失败时,我可以使用 Sequel Pro 或 SSH 查询正在运行的 Docker 容器并进行查询。那么可能是 Node.js 无法访问 MySQL 容器的情况?


    error: connect ECONNREFUSED 127.0.0.1:3307
    code: 'ECONNREFUSED',
    errno: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 3307,
    fatal: true

【问题讨论】:

试试你的本地 ip - 例如192.168.0.8 @EvgenyKolyakov 这在生产环境中不起作用,因为我的本地主机不在身边。 Docker 应该链接容器。 “nodejs”docker里面有数据库服务器吗?? 【参考方案1】:

这个:

mysql:
    image: mysql:5.7
    environment:
    ...
    ports:
      - "3307:3306"

表示Docker会将宿主机的3307端口映射到容器的3306端口。所以你可以从续集访问localhost:3307

但是不代表容器在监听3307;该容器实际上仍在收听3306。当其他容器尝试访问mysql DNS 时,它会被转换为内部容器IP,因此您必须连接到3306

所以你的节点配置应该是这样的:

const config = 
    host: 'mysql',
    database: 'mydb',
    port: '3306',
    user: 'mysql',
    password: '1234',
    connectionLimit: 10

这在你的 docker-compose.yml 中:

command: ["./wait-for-it.sh", "mysql:3306"]

【讨论】:

command: ["./wait-for-it.sh", "mysql:3306"] 添加此获取错误/usr/local/bin/docker-entrypoint.sh: line 390: /wait-for-it.sh: No such file or directory

以上是关于Node.js 连接到 MySQL Docker 容器 ECONNREFUSED的主要内容,如果未能解决你的问题,请参考以下文章

Docker - Node.js + MongoDB - “错误:无法连接到 [localhost:27017]”

当应用程序在本地运行时,Node.js 能够连接到 MySQL 容器,但当应用程序在容器中运行时无法连接

从 Java(Spring Boot)或 Node.js 检查/连接到在 docker 中运行的 Redis

无法连接到 mySQL 服务器,Windows 10/Node.js

Node.js - 连接到 MySQL 数据库服务器

如何将 node.js 连接到 mySQL 数据库? [复制]