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

Docker化Rails应用连接本地MongoDB遇NoServerAvailable错误的解决办法

解决Docker化Rails应用连接本地MongoDB的问题

我来帮你排查这个Mongo连接失败的问题,大概率是网络访问限制或者配置细节出了问题,咱们一步步来解决:

1. 修复mongoid.yml里的环境变量取值错误

你mongoid.yml里的环境变量写法有问题,ERB模板里不需要转义双引号,当前的<%= ENV[\"MONGO_CONNECTION_STRING\"] %>会导致无法正确读取环境变量,应该改成:

development:
  clients:
    default:
      database: elagi
      hosts:
        - <%= ENV["MONGO_CONNECTION_STRING"] %>
      options:
        user: 'admin'
        password: 'admin123'
        max_pool_size: 20
        wait_queue_timeout: 15
  options:
    raise_not_found_error: false

修改后可以进入Rails容器执行echo $MONGO_CONNECTION_STRING,确认输出是192.168.1.109:27017,验证变量能被正确读取。

2. 允许MongoDB接收容器网络的请求

默认情况下MongoDB只绑定127.0.0.1,也就是仅允许宿主机本地访问,而Docker容器属于独立的网络空间,因此无法连接。你需要修改MongoDB的配置文件:

  • 找到mongod.conf(常见路径:/etc/mongod.conf或/usr/local/etc/mongod.conf)
  • 将net.bindIp改为0.0.0.0(开发环境允许所有IP访问,方便测试),或者添加宿主机的局域网IP:127.0.0.1,192.168.1.109
  • 重启MongoDB服务:sudo systemctl restart mongod(根据你的操作系统调整命令)

3. 验证MongoDB账号的权限与正确性

先在宿主机用命令行测试连接,确认账号密码和数据库权限没问题:

mongo mongodb://admin:admin123@192.168.1.109:27017/elagi

如果连接失败,检查以下几点:

  • 账号admin是否存在,且拥有elagi数据库的读写权限
  • 密码是否拼写正确
  • 如果是MongoDB 4.0+版本,建议在mongoid.yml的options里加上auth_source: admin(因为admin账号通常在admin数据库下创建):
options:
  user: 'admin'
  password: 'admin123'
  auth_source: 'admin' # 新增该配置,指定认证源数据库
  max_pool_size: 20
  wait_queue_timeout: 15

4. 检查宿主机防火墙设置

如果宿主机开启了防火墙,需要允许27017端口的入站请求。以Ubuntu为例,执行:

sudo ufw allow 27017

也可以临时关闭防火墙测试,确认是不是防火墙阻止了容器的连接请求。

5. 可选:用Docker Host网络快速验证(不推荐生产环境使用)

如果以上步骤都无法解决,你可以尝试给容器开启Host网络模式,让容器直接使用宿主机的网络栈。此时MONGO_CONNECTION_STRING可以设为localhost:27017,修改docker-compose.yml如下:

elagi_app:
  build:
    context: '..'
    dockerfile: 'docker/Dockerfile'
  network_mode: host # 新增该行
  environment:
    RAILS_ENV: development
    ELASTICSEARCH_URL: 192.168.1.109:9200
    MONGO_CONNECTION_STRING: localhost:27017 # 修改为localhost
    REDIS_URL: redis://localhost:6379 # 同步修改Redis地址
  # 移除ports映射,Host网络无需端口映射
  volumes:
    - ./../app:/myapp/app
    - ./../config:/myapp/config
    - ./../lib:/myapp/lib
    - ./../db:/myapp/db
    - ./../spec:/myapp/spec

sidekiq:
  build:
    context: '..'
    dockerfile: 'docker/Dockerfile'
  network_mode: host # 新增该行
  environment:
    RAILS_ENV: development
    ELASTICSEARCH_URL: 192.168.1.109:9200
    MONGO_CONNECTION_STRING: localhost:27017 # 修改为localhost
    REDIS_URL: redis://localhost:6379 # 同步修改Redis地址
  volumes:
    - ./../app:/myapp/app
    - ./../config:/myapp/config
    - ./../lib:/myapp/lib
    - ./../db:/myapp/db
    - ./../spec:/myapp/spec
  depends_on:
    - 'redis'
  command: 'sidekiq -C config/sidekiq.yml'

注意:这种方式会打破容器的网络隔离,仅建议在开发环境快速验证问题,生产环境不推荐使用。

按照上述步骤排查,应该能解决Mongo::Error::NoServerAvailable的问题。

内容的提问来源于stack exchange,提问作者Ahmed Fouad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:17:39