Node.js连接到MySQL Docker容器ECONNREFUSED [英] Node.js connect to MySQL Docker container ECONNREFUSED

查看:100
本文介绍了Node.js连接到MySQL Docker容器ECONNREFUSED的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Before you flag this question as a duplicate, please note that I did read other answers, but it didn't solve my problem.

我有一个包含两个服务的Docker组成文件:

I have a Docker compose file consisting of two services:

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:

/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准备好接受传入连接时才使用

After docker-compose up --build the services start up, however the "wait-for-it.sh" script times out when waiting for mySQL to start (so temporarily I am not using it when testing for DB connectivity, I just wait until the console shows that MySQL is ready for accepting incoming connections)

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

When MySQL is running from the host machine I can login using Sequel Pro and query the DB and get the sample records from ./mysql/migrations

我还可以通过SSH进入正在运行的MySQL容器并执行相同的操作.

I can also SSH into the running MySQL container and do the same.

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

However, my Node.js app yields ECONNREFUSED 127.0.0.1:3307 when connecting

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)
    })
}

点击网址时调用路由/

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容器的情况?

It's unlikely to be a race condition because at the same time when Node.js fails I can query using Sequel Pro or SSH into the running Docker container and query. So it's probably a case of Node.js not being able to access to MySQL container?

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

推荐答案

此:

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

表示Docker将主机的3307端口映射到容器的3306端口.因此,您可以从Sequel访问localhost:3307.

Means that Docker will map the 3307 port of the host to the 3306 port of the container. So you can access from Sequel to localhost:3307.

但是,这并不意味着容器正在监听3307;容器实际上仍在监听3306.当其他容器尝试访问mysql DNS时,它将转换为内部容器IP,因此您必须连接到3306.

However, it does not mean that the container is listenting to 3307; the container is in fact still listening to 3306. When others containers tries to access the mysql DNS, it gets translated to the internal container IP, therefore you must connect to 3306.

因此,您的节点配置应如下所示:

So your node config should look like:

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

这在您的docker-compose.yml中:

And this in your docker-compose.yml:

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

这篇关于Node.js连接到MySQL Docker容器ECONNREFUSED的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆