简体   繁体   English

Node.js连接到MySQL Docker容器ECONNREFUSED

[英]Node.js connect to MySQL Docker container ECONNREFUSED

Before you flag this question as a duplicate, please note that I did read other answers, but it didn't solve my problem. 在您将此问题标记为重复之前,请注意我确实阅读了其他答案,但这并没有解决我的问题。

I have a Docker compose file consisting of two services: 我有一个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: /网络/ 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" ]

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) docker-compose up --build之后docker-compose up --build 构建服务启动,但是等待mySQL启动时“wait-for-it.sh”脚本超时(所以暂时我在测试数据库连接时没有使用它,我只是等待直到控制台显示MySQL已准备好接受传入连接)

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 当MySQL从主机运行时,我可以使用Sequel Pro登录并查询数据库并从./mysql/migrations获取样本记录

在此输入图像描述 在此输入图像描述

I can also SSH into the running MySQL container and do the same. 我也可以通过SSH连接到正在运行的MySQL容器并执行相同操作。

However, my Node.js app yields ECONNREFUSED 127.0.0.1:3307 when connecting 但是,我的Node.js应用程序在连接时会产生ECONNREFUSED 127.0.0.1:3307

MySQL init: 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 query: 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)
    })
}

Route invoked when hitting 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
    });
});

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. 它不太可能是竞争条件,因为在Node.js失败的同时,我可以使用Sequel Pro或SSH查询正在运行的Docker容器和查询。 So it's probably a case of Node.js not being able to access to MySQL container? 所以这可能是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
}

This: 这个:

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

Means that Docker will map the 3307 port of the host to the 3306 port of the container. 意味着Docker将主机的3307端口映射到容器的3306端口。 So you can access from Sequel to localhost:3307 . 所以你可以从Sequel访问localhost:3307

However, it does not mean that the container is listenting to 3307 ; 但是,这并不意味着容器持续到3307 ; the container is in fact still listening to 3306 . 事实上,容器仍然在听3306 When others containers tries to access the mysql DNS, it gets translated to the internal container IP, therefore you must connect to 3306 . 当其他容器尝试访问mysql DNS时,它会转换为内部容器IP,因此您必须连接到3306

So your node config should look like: 因此,您的节点配置应如下所示:

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

And this in your docker-compose.yml: 这在你的docker-compose.yml中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM