Docker部署Rails+Elasticsearch时出现Faraday::ConnectionFailed错误
问题:Docker Compose部署Rails+MySQL+Elasticsearch时Elasticsearch连接失败
错误信息
部署后触发搜索功能出现500错误,具体异常如下:
"status": 500, "error": "Internal Server Error", "exception": "#<Faraday::ConnectionFailed wrapped=#<Errno::EADDRNOTAVAIL: Failed to open TCP connection to localhost:9200 (Cannot assign requested address - connect(2) for [::1]:9200)>>"
当前配置
Docker Compose配置(docker-compose.yml)
version: "3.7" services: app: build: . command: bundle exec rails s -p 3000 -e development -b '0.0.0.0' ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: DB_USER: root DB_NAME: insta-api DB_PASSWORD: 123456789 DB_HOST: mysql mysql: image: mysql:5.7 volumes: - insta-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: 123456789 MYSQL_DATABASE: insta-api elasticsearch: image: elasticsearch:7.17.6 hostname: "elasticsearch" environment: - discovery.type=single-node ports: - "9200:9200" ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 mem_limit: 1g cap_add: - IPC_LOCK volumes: insta-mysql-data:
Elasticsearch初始化文件(./config/initializers/elasticsearch.rb)
config = { host: "http://localhost:9200/", transport_options: { request: { timeout: 5 } } } if File.exists?("config/elasticsearch.yml") config.merge!(YAML.load_file("config/elasticsearch.yml")[Rails.env].deep_symbolize_keys) end Elasticsearch::Model.client = Elasticsearch::Client.new(config)
Elasticsearch环境配置(./config/elasticsearch.yml)
#./config development: &default host: 'http://localhost:9200/' transport_options: request: timeout: !!integer 300 test: <<: *default staging: <<: *default production: host: 'http://10.50.11.50/' transport_options: request: timeout: !!integer 300
问题原因
Docker Compose创建的容器处于独立网络环境中,localhost在容器内部指向自身,而非宿主机或其他容器。Rails容器中用localhost:9200请求Elasticsearch,实际是在Rails容器内部查找9200端口,导致连接失败。
解决方法
1. 修改Elasticsearch连接地址
将config/elasticsearch.yml中development环境的host改为http://elasticsearch:9200/——Docker Compose会自动为服务创建DNS解析,服务名elasticsearch可直接访问对应容器。
修改后的配置文件:
#./config development: &default host: 'http://elasticsearch:9200/' transport_options: request: timeout: !!integer 300 test: <<: *default staging: <<: *default production: host: 'http://10.50.11.50/' transport_options: request: timeout: !!integer 300
2. 重启服务
执行命令重启所有容器,让配置生效:
docker-compose down docker-compose up --build
3. 验证连接(可选)
进入Rails容器内部,用curl测试Elasticsearch连通性:
docker-compose exec app curl http://elasticsearch:9200
若返回Elasticsearch节点信息,说明连接已正常。
额外说明
- Docker Compose默认以服务名作为容器的DNS名称,即使不设置
hostname: "elasticsearch",也可通过服务名访问Elasticsearch容器。 - 若仍有问题,可查看Elasticsearch容器日志确认节点状态:
docker-compose logs elasticsearch
内容的提问来源于stack exchange,提问作者Muhammad
相关产品推荐
相关产品推荐

