Я пытаюсь заставить мое приложение Node.js взаимодействовать с моей базой данных Elasticsearch при работе в той же сети моста в Docker. Я использую файл 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-app
и elasticsearch
были обнаружены на создается мостовая сеть Docker my_app_backend с именами их служб. Официальная документация Docker гласит, что «служба доступна по имени хоста». Мое намерение состоит в том, чтобы связаться с ней. asticsearch по адресу "http://elasticsearch: 9200 ".
Определение соединения с БД внутри Node.js приложения (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 Failed\n', err);
}
}
checkConnection();
module.exports.client = client;
В приведенном ниже сообщении показан результат попытки приложения Node.js подключиться к Elasticsearch через переменную process.env.ES_HOST'asticsearch '(как определено в файле docker -compose.yml) и выполнено при запуске контейнеров Сообщение об ошибке показывает пару консольных журналов, которые я установил, чтобы убедиться, что переменные имеют правильные значения.
IP-адрес, показанный после ECONNREFUSED, - то, чем движок 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 или я упускаю что-то очень очевидное? Заранее благодарю за помощь!