使用Docker Compose部署Rails无法连接localhost:9200 Elasticsearch问题
问题根因
你遇到的报错由两个配置错误共同导致:
- Elasticsearch服务单独绑定了
elastic自定义网桥,但Rails对应的web服务没有加入该网络,两个服务不在同一网段下无法通过服务名互通 - Rails应用内硬编码了Elasticsearch连接地址为
localhost:9200,容器内的localhost指向的是web容器本身,而非Elasticsearch容器或宿主机
解决步骤
1. 修正docker-compose网络配置
给web服务添加elastic网络配置,同时新增Elasticsearch连接地址的环境变量供Rails读取,修改后的web服务配置如下:
web: build: context: . dockerfile: docker/Dockerfile command: bundle exec rails server -b 0.0.0.0 environment: POSTGRES_HOST: db POSTGRES_PASSWORD: password ELASTICSEARCH_URL: http://elasticsearch:9200 # 新增ES地址环境变量 volumes: - .:/app ports: - "3000:3000" depends_on: - db - elasticsearch # 可选配置,确保ES先启动再启Rails entrypoint: docker/entrypoint.sh networks: # 新增网络配置,和ES加入同一网桥 - elastic
2. 修改Rails的Elasticsearch连接配置
找到项目中Elasticsearch客户端的初始化代码(一般路径为config/initializers/elasticsearch.rb),将连接地址改为从环境变量读取,不要写死localhost:
Elasticsearch::Client.new(url: ENV.fetch("ELASTICSEARCH_URL", "http://localhost:9200"))
如果使用的是searchkick等封装好的Gem,直接在对应配置处指定地址为上述环境变量即可。
3. 重启服务生效
执行以下命令重新加载配置启动服务:
docker-compose down docker-compose up -d
验证
启动完成后进入web容器测试连通性:
docker-compose exec web curl http://elasticsearch:9200
返回你之前在宿主机看到的ES信息即代表配置正常,此时再访问Rails应用就不会再出现连接报错。
内容的提问来源于stack exchange,提问作者Warden
相关产品推荐
相关产品推荐

