Node.js 连接到 MySQL Docker 容器 ECONNREFUSED
P粉296080076
P粉296080076 2024-01-21 15:41:18
0
1
640

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

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

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 启动时超时(所以在测试 DB 时暂时不使用它)连接,我只是等到控制台显示 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
}


P粉296080076
P粉296080076

全部回复(1)
P粉399090746

这个:

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

表示Docker会将主机的3307端口映射到容器的3306端口。因此您可以从 Sequel 访问 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"]

注意:wait-for-it.sh 脚本来自: https://github.com/vishnubob/wait-for-it

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板