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

Cloud Run部署含Express、Mongoose的Docker容器遇Mongo连接错误

Cloud Run部署Node.js+MongoDB容器无法连接MongoDB的解决方法

问题描述

我尝试在Cloud Run上部署首个容器,使用搭载MongoDB的Node.js服务器。本地通过Docker Compose可正常启动容器,但上传至Cloud Run后,服务器能启动却无法连接MongoDB,控制台报错getaddrinfo ENOTFOUND mongo。相关配置及日志如下:

错误日志

Apr 21 01:12:30 AM  MongoServerSelectionError: getaddrinfo ENOTFOUND mongo
Apr 21 01:12:30 AM      at Timeout._onTimeout (/opt/render/project/src/node_modules/mongodb/lib/sdam/topology.js:277:38)
Apr 21 01:12:30 AM      at listOnTimeout (internal/timers.js:555:17)
Apr 21 01:12:30 AM      at processTimers (internal/timers.js:498:7) {
Apr 21 01:12:30 AM    reason: TopologyDescription {
Apr 21 01:12:30 AM      type: 'Unknown',
Apr 21 01:12:30 AM      servers: Map(1) { 'mongo:27017' => [ServerDescription] },
Apr 21 01:12:30 AM      stale: false,
Apr 21 01:12:30 AM      compatible: true,
Apr 21 01:12:30 AM      heartbeatFrequencyMS: 10000,
Apr 21 01:12:30 AM      localThresholdMS: 15,
Apr 21 01:12:30 AM      setName: null,
Apr 21 01:12:30 AM      maxElectionId: null,
Apr 21 01:12:30 AM      maxSetVersion: null,
Apr 21 01:12:30 AM      commonWireVersion: 0,
Apr 21 01:12:30 AM      logicalSessionTimeoutMinutes: null
Apr 21 01:12:30 AM    },
Apr 21 01:12:30 AM    code: undefined,
Apr 21 01:12:30 AM    [Symbol(errorLabels)]: Set(0) {}
Apr 21 01:12:30 AM  }
Apr 21 01:12:30 AM  (node:75) UnhandledPromiseRejectionWarning: MongooseServerSelectionError: getaddrinfo ENOTFOUND mongo
Apr 21 01:12:30 AM      at _handleConnectionErrors (/opt/render/project/src/node_modules/mongoose/lib/connection.js:755:11)
Apr 21 01:12:30 AM      at NativeConnection.openUri (/opt/render/project/src/node_modules/mongoose/lib/connection.js:730:11)
Apr 21 01:12:30 AM  (Use `node --trace-warnings ...` to show where the warning was created)
Apr 21 01:12:30 AM  (node:75) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)

Dockerfile

FROM node

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install
COPY . .

EXPOSE 8080

CMD [ "node", "server.js" ]

docker-compose.yml

version: "3"
services:
  web:
    build: .
    ports:
      - "8080:8080"
    external_links:
       - "mongo"

  mongo:
  container_name: mongo
  image: mongo
  volumes:
  - ./data:/data/db
  ports:
  - '27012:27017'

MongoDB连接代码

mongoose.connect('mongodb://mongo:27017/toDoBeta',  {
    useNewUrlParser: true,
})

解决建议

  • 核心原因:Cloud Run是单容器部署环境,不支持Docker Compose的多容器服务发现机制。本地用mongo作为主机名能生效,是因为Docker Compose的默认网络会自动解析服务名;但Cloud Run中没有这个DNS记录,所以无法解析地址。

  • 推荐方案:使用托管式MongoDB服务

    1. 创建MongoDB Atlas免费集群,获取包含用户名、密码的连接字符串
    2. 修改Node.js代码,通过环境变量读取连接字符串,避免硬编码:
      const mongoUri = process.env.MONGODB_URI;
      mongoose.connect(mongoUri, { useNewUrlParser: true });
      
    3. 在Cloud Run部署配置中添加MONGODB_URI环境变量,值为Atlas的连接字符串
  • 备选方案:使用Google Cloud原生托管数据库
    选择Cloud Memorystore for MongoDB(完全托管MongoDB),配置Cloud Run与该服务的VPC连接,之后在代码中使用实例的内部IP或域名进行连接。

  • 不推荐方案:将MongoDB与Node.js打包到同一容器
    Cloud Run容器是无状态的,扩缩容会导致多实例数据不一致;且容器重启后数据会丢失,完全不适合运行MongoDB这类有状态数据库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 14:54:56