"ConnectionError: connect ECONNREFUSED",无法将 Node.js app 和 Elasticsearch 数据库与 Docker Compose 连接



我正试图让我的Node.js应用程序在Docker中的同一网桥网络上运行时与我的Elasticsearch数据库对话。我使用docker-compose.yml文件进行配置。以下是我收到的相关比特和错误消息。

docker-compose.yml

version: '3'
services:
express-app:
build: /path/to/app
container_name: my_app
depends_on:
- 'elasticsearch'
environment:
- NODE_ENV=local
- ES_HOST=elasticsearch
- PORT=3000
ports:
- 3000:3000
networks:
- backend
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0
container_name: es-master
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- 9200:9200
- 9300:9300
networks:
- backend
volumes:
esdata:
driver: local
networks:
backend:

我希望两个服务(express-appelasticsearch(都能在创建的Docker网桥网络"my_app_backend"上被发现,并附上它们的服务名称。Docker的官方文档指出"服务可以在主机名上访问"。我的意图是在地址"http://elasticsearch:9200".

Node.js应用程序中的DB连接定义(server/DB/index.js(

const { Client } = require('@elastic/elasticsearch');
const hostname = process.env.ES_HOST || 'localhost';
const client = new Client({
node: `http://${hostname}:9200`,
log: 'error'
});
async function checkConnection () {
let isConnected = false;
console.log('Connecting to host', hostname);
try {
const health = await client.cluster.health({});
console.log(health);
isConnected = true;
} catch (err) {
console.log('process.env.ES_HOST', process.env.ES_HOST);
console.log('Connection Failedn', err);
}
}
checkConnection();
module.exports.client = client;

下面的消息显示了Node.js应用程序试图通过process.env.ES_HOST变量"Elasticsearch"(如docker-compose.yml文件中所定义(连接到Elasticsearch并在容器运行时执行的结果。错误消息显示了我放置的几个控制台日志,用于检查变量的值是否正确。

ECONNREFUSED之后显示的IP地址是Docker引擎用以替换"弹性搜索"的地址。当我运行输出容器网络地址的docker network inspect my_app_backend时,也可以发现这一点。

... (redacted)
"MacAddress": "02:42:ac:14:00:03",
"IPv4Address": "172.20.0.3/16",
"IPv6Address": ""

错误消息

> NODE_ENV=production node ./server/index.js
Connecting to host elasticsearch
Server listening on port 3000!
process.env.ES_HOST elasticsearch
Connection Failed
ConnectionError: connect ECONNREFUSED 172.20.0.3:9200
at onResponse (/src/app/node_modules/@elastic/elasticsearch/lib/Transport.js:214:13)
at ClientRequest.<anonymous> (/src/app/node_modules/@elastic/elasticsearch/lib/Connection.js:98:9)
at ClientRequest.emit (events.js:311:20)
at Socket.socketErrorListener (_http_client.js:426:9)
at Socket.emit (events.js:311:20)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
name: 'ConnectionError',
meta: {
body: null,
statusCode: null,
headers: null,
warnings: null,
meta: {
context: null,
request: [Object],
name: 'elasticsearch-js',
connection: [Object],
attempts: 3,
aborted: false
}
}
}

此外,我想注意的是,应用程序在启动时未能连接,但当我通过docker exec -it express-app sh进入应用程序容器,编辑数据库连接代码并硬编码数据库的IP地址(172.20.0.3(,然后重新启动节点应用程序时,应用程序成功连接到数据库。

在尝试通过docker compose实现完全自动化的过程中,我做错了什么?这是Elasticsearch的一个怪癖,还是我遗漏了一些非常明显的东西?提前感谢您的帮助!

在express_app 中使用container_name : es-master而不是elasticsearch作为ES_HOST环境变量

ES_HOST : es-master

我认为你应该链接弹性搜索容器

version: '3'
services:
express-app:
build: /path/to/app
container_name: my_app
restart: always
depends_on:
- 'elasticsearch'
environment:
- NODE_ENV=local
- ES_HOST=elasticsearch
- PORT=3000
ports:
- 3000:3000
networks:
- backend
links: 
- elasticsearch
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0
container_name: es-master
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- 9200:9200
- 9300:9300
networks:
- backend
volumes:
esdata:
driver: local
networks:
backend:

最新更新