Docker Compose环境下Python连接Elasticsearch及使用LangChain-Elasticsearch均遇连接拒绝问题
我来一步步帮你拆解排查这两个连接问题:
先说说你第一个解决的连接问题(供后续参考)
你一开始在Jupyter容器里用localhost作为Elasticsearch的host,这是Docker新手常踩的网络坑——容器里的localhost指的是容器自身,不是宿主机,自然访问不到另一个独立的Elasticsearch容器。后来你把host改成Docker Compose里ES服务的名称elasticsearch就能拿到info,这完全正确,因为默认情况下Compose会给所有服务创建共享网络,用服务名就能直接跨容器访问服务。
另外提一句:你已经在ES配置里开了xpack.security.enabled=false,也就是关闭了所有安全验证,所以Python代码里的basic_auth参数其实是多余的,传了反而可能引发不必要的验证报错,建议直接去掉。
重点解决第二个问题:LangChain-Elasticsearch仍报连接拒绝
既然ES客户端已经能正常返回info(),那这个新的Errno111大概率不是ES的问题,得从这几个方向排查:
1. 检查Ollama Embeddings的连接是关键
你的代码里用了OllamaEmbeddings,但我看你的Docker Compose配置里没部署Ollama服务!如果Ollama是在宿主机上跑的,那Jupyter容器里的localhost同样访问不到它——和之前ES的坑一模一样!
给你两个解决思路:
- 推荐方案:把Ollana也加入Docker Compose
在你的docker-compose.yml里加一个Ollama服务:
然后修改Python里的Ollama配置,用服务名访问:ollama: container_name: ollama image: ollama/ollama:latest ports: - 11434:11434 volumes: - ./ollama/models:/root/.ollama/models # 挂载模型目录,避免重复下载embeddings = OllamaEmbeddings( model="snowflake-arctic-embed", base_url="http://ollama:11434" # 用Ollama的服务名替代localhost ) - 临时方案:用宿主机IP访问Ollama
如果坚持在宿主机跑Ollama,就把base_url改成宿主机的实际局域网IP(比如192.168.1.100),或者Docker默认网关IP(一般是172.17.0.1),不要用localhost。
2. 确认ElasticsearchStore复用的客户端配置正确
一定要确保传给ElasticsearchStore的elasticsearch_client是已经修正后的版本:host是elasticsearch、没有多余的basic_auth参数。如果客户端还是残留了旧的localhost配置,那肯定还是会报错。
3. 手动验证容器网络连通性
可以先在Jupyter容器里做个小测试,确认网络没问题:
# 进入Jupyter容器 docker exec -it jupyter bash # 测试能不能ping通ES容器(能ping通说明网络连通) ping elasticsearch # 测试能不能直接访问ES服务 curl http://elasticsearch:9200
如果ping不通,说明两个服务不在同一个Docker网络里——检查你的Compose配置有没有给服务指定不同的自定义网络,默认情况下所有服务都会在Compose自动创建的默认网络里,是可以互通的。
4. 版本兼容性小检查
你用的elasticsearch==8.17.0和langchain-elasticsearch==0.3.0版本是兼容的,但如果以上都没问题,可以尝试把langchain-elasticsearch升级到最新版,避免版本适配的小bug:
pip install --upgrade langchain-elasticsearch
给你一个完整的修正后代码示例
from elasticsearch import Elasticsearch from langchain_ollama import OllamaEmbeddings from langchain_elasticsearch import ElasticsearchStore # 初始化正确的ES客户端 elasticsearch_client = Elasticsearch( [{"host": "elasticsearch", "port": 9200, "scheme": "http"}] ) # 先确认ES连接正常 print("ES连接状态:", elasticsearch_client.info()) # 初始化Ollama Embeddings(假设Ollama已加入Compose,服务名是ollama) embeddings = OllamaEmbeddings( model="snowflake-arctic-embed", base_url="http://ollama:11434" ) # 初始化LangChain的ElasticsearchStore es_vector_store = ElasticsearchStore( es_connection=elasticsearch_client, index_name="langchain", embedding=embeddings ) # 测试相似性搜索 result = es_vector_store.similarity_search(query="Hello world") print("搜索结果:", result)
备注:内容来源于stack exchange,提问作者Baptiste LESNE

