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