Node.js连接到MySQL Docker容器ECONNREFUSED

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

我有一个由两个服务组成的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"] 

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

当MySQL从主机运行时,我可以使用Sequel Prologin并查询数据库,并从./mysql/migrations获取样本logging

在这里输入图像说明 在这里输入图像说明

我也可以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 } 

这个:

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

意思是说Docker会将主机的3307端口映射到容器的3306端口。 所以你可以从续集访问localhost:3307

但是,这并不意味着集装箱正在聆听3307 ; 这个容器其实还在听3306 。 当其他容器试图访问mysql DNS时,它将被转换为内部容器IP,因此您必须连接到3306

所以你的节点configuration应该如下所示:

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

而这在你的docker-compose.yml中:

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