I am currently attempting to containerize an application which includes writing to a database with Elasticsearch, but get connection problems. The docker-compose.yml
file currently looks something like this:
version: "3"
services:
es:
image: docker.elastic.co/elasticsearch/elasticsearch:7.5.1
container_name: es
environment:
- node.name=es
- cluster.name=es-docker-cluster
- cluster.initial_master_nodes=es
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
ports:
- 9200:9200
volumes:
- esdata:/usr/share/elasticsearch/data
networks:
- dash-network
dash:
build: .
depends_on:
- es
ports:
- 5000:5000
volumes:
- .:/usr/src/dash
networks:
- dash-network
volumes:
esdata:
driver: local
networks:
dash-network:
driver: bridge
My Python code includes the following:
import elasticsearch
es = elasticsearch.Elasticsearch([{'host': 'es', 'port': 9200}])
es.index(index="spam", body={'eggs': 11})
When I run docker-compose up
, however, the last line in that segment of code brings up the following error:
esmqtt_1 | elasticsearch.exceptions.ConnectionError: ConnectionError(<urllib3.connection.HTTPConnection object at 0x7f2f60b53dd0>: Failed to establish a new connection: [Errno 111] Connection refused) caused by: NewConnectionError(<urllib3.connection.HTTPConnection object at 0x7f2f60b53dd0>: Failed to establish a new connection: [Errno 111] Connection refused)
As an experiment, I halted the script for a long time before it ran this code, shelled into the container, and ran each of these three commands sequentially. It worked:
elliot@elliot-VirtualBox:~/path/to/dash$ sudo docker exec -it dash_dash_1 sh
# python
Python 3.7.6 (default, Jan 3 2020, 23:24:26)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import elasticsearch
>>> es = elasticsearch.Elasticsearch([{'host': 'es', 'port': 9200}])
>>> es.index(index="spam", body={'eggs': 11})
{'_index': 'spam', '_type': '_doc', '_id': '3Ey5zm8B7hzXos4SVZsF', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 0, '_primary_term': 1}
I don't know why my code fails when run by the Dockerfile, but when I shell in, it works. Why does it fail to connect in the former instance, but succeed in the latter instance? All tips or advice welcome!
It tried to run the different containers at the same time, resulting in the dash
container attempting to connect before Elasticsearch had finished being set up. I now use the following loop in order to check that it is ready before proceeding.
while True:
try:
es.search(index="")
break
except (
elasticsearch.exceptions.ConnectionError,
elasticsearch.exceptions.TransportError
):
time.sleep(1)