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
相关产品推荐
相关产品推荐

