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

Docker容器间MongoDB连接异常:外部可连内部应用无法连接

问题:Docker网络中外部可连接Mongo但应用容器无法连接

所有服务通过docker-compose.yml容器化(无关代码已省略):

proxy:
    image: nginx:alpine    
    ports:
      - '80:80'
      - '443:443'    
    networks:
      - myNetwork

app-server:  
    ports:
      - '3000:3000'
    volumes:
      - ./:/app
      - /app/node_modules    
    networks:
      - myNetwork

mongo6:   
    networks:
      - myNetwork
    ports:
      - 27017:27017    

networks:
  myNetwork:
    external: true

尝试通过Nginx代理Mongo实例,nginx.conf相关配置如下:

upstream docker-mongo {
   server mongo6:27017;
}

server {
   listen 443 ssl;
   server_name mongo.mysite.co;
   ...

   location / {
      proxy_pass http://docker-mongo;
   }
}

已为数据库mydb创建Mongo用户mongo-mydb-user。当前可通过外部工具(如Compass)使用连接字符串mongodb://mongo-mydb-user:pass@mongo.mysite.com:27017/mydb连接mongo6容器,但app-server容器内代码使用相同连接字符串却无法连接。

切换配置为network_mode: host并修改Nginx的proxy_pass指向http://localhost:27017后,代码可连接但外部Compass无法连接,不想使用该模式,且另一台相同Docker网络配置的机器可同时支持外部和应用代码连接。

服务器/etc/hosts配置如下:

127.0.0.1   localhost
::1     localhost ip6-localhost ip6-loopback
ff02::1     ip6-allnodes
ff02::2     ip6-allrouters

# Auto-generated hostname. Please do not remove this comment.
31.123.45.678 mysite.vps.local mysite

报错信息:

Failed to connect to mongo MongooseServerSelectionError: Server selection timed out after 30000 ms
server  |     at Connection.openUri (/app/node_modules/mongoose/lib/connection.js:825:32)
server  |     at /app/node_modules/mongoose/lib/index.js:414:10
server  |     at /app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:41:5
server  |     at new Promise (<anonymous>)
server  |     at promiseOrCallback (/app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:40:10)
server  |     at Mongoose._promiseOrCallback (/app/node_modules/mongoose/lib/index.js:1288:10)
server  |     at Mongoose.connect (/app/node_modules/mongoose/lib/index.js:413:20)
server  |     at App.connectToDatabase (/app/dist/app.js:47:41)
server  |     at new App (/app/dist/app.js:117:18)
server  |     at main (/app/dist/server.js:42:21) {
server  |   reason: TopologyDescription {
server  |     type: 'Single',
server  |     servers: Map(1) { 'mongo.cardstop.co:27017' => [ServerDescription] },
server  |     stale: false,
server  |     compatible: true,
server  |     heartbeatFrequencyMS: 10000,
server  |     localThresholdMS: 15,
server  |     setName: null,
server  |     maxElectionId: null,
server  |     maxSetVersion: null,
server  |     commonWireVersion: 0,
server  |     logicalSessionTimeoutMinutes: null
server  |   },
server  |   code: undefined
server  | }
问题分析与解决办法

核心原因

  1. 容器内DNS解析与网络路径问题:
    应用容器中使用mongo.mysite.co时,会通过服务器/etc/hosts解析到VPS公网IP31.123.45.678,此时容器尝试访问该公网IP的27017端口。但Docker默认网络配置下,容器访问自身主机的公网IP可能存在hairpin NAT问题,导致连接超时;而外部Compass从外部网络访问公网IP,不受此限制,所以能正常连接。

  2. Nginx配置错误:
    Mongo使用的是TCP协议,但当前Nginx配置用的是HTTP代理模块,无法正确处理Mongo的二进制TCP流量,所以该代理配置实际上无效,外部Compass能连接是直接访问了mongo6容器映射的27017端口,而非通过Nginx的443端口。

解决步骤

方案1:直接使用Docker服务名连接(推荐)

同一Docker网络内的容器可通过服务名直接通信,无需走公网或Nginx代理:

  • 修改应用代码中的Mongo连接字符串,将mongo.mysite.co替换为mongo6,最终连接字符串为:
    mongodb://mongo-mydb-user:pass@mongo6:27017/mydb
    
    此方式利用Docker内置DNS服务,容器间直接通信,性能和稳定性最优。

方案2:容器内域名映射(保持统一连接字符串)

如果需要保持连接字符串不变,可在app-server容器内配置域名映射,将mongo.mysite.co指向Docker网络内的mongo6服务:

  • 修改docker-compose.yml,为app-server添加extra_hosts配置:
    app-server:
      # ...原有配置
      extra_hosts:
        - "mongo.mysite.co:mongo6"
    
    这样容器内访问mongo.mysite.co时,会直接解析到mongo6服务,走Docker网络通信。

方案3:修复Nginx的Mongo代理(如需通过443端口访问)

如果需要通过Nginx的443端口代理Mongo流量,需使用Nginx的stream模块处理TCP协议:

  • 修改Nginx配置,添加stream块:
    stream {
        upstream mongo_backend {
            server mongo6:27017;
        }
        server {
            listen 443 ssl;
            proxy_pass mongo_backend;
            # 配置SSL证书路径,例如:
            ssl_certificate /path/to/cert.pem;
            ssl_certificate_key /path/to/key.pem;
        }
    }
    
  • 此时连接字符串需改为使用443端口:
    mongodb://mongo-mydb-user:pass@mongo.mysite.co:443/mydb?ssl=true
    
    注意需确保Mongo服务支持SSL连接,或调整Nginx配置为不加密代理(不推荐生产环境)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:43:14