You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:05:28