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

AWS EC2部署Golang+MongoDB+Docker-Compose时MongoDB连接失败排查

问题分析与解决方案

针对你在AWS EC2上部署Golang+MongoDB+Docker-Compose应用时出现的容器内MongoDB连接超时问题,结合你的配置和报错信息,以下是几个排查方向和解决办法:

1. 检查外部Docker网络与卷的有效性

你在docker-compose.yml中指定了external: true的mongo-go网络和mongo-data卷,这意味着两者需要手动提前在EC2实例上创建,否则容器无法加入正确的网络或挂载存储。

  • 排查与创建命令:
    # 查看已存在的Docker网络
    docker network ls
    # 若不存在mongo-go网络则创建
    docker network create mongo-go
    
    # 查看已存在的Docker卷
    docker volume ls
    # 若不存在mongo-data卷则创建
    docker volume create mongo-data
    

2. 解决depends_on的服务就绪局限性

depends_on仅保证MongoDB容器先启动,但不确保MongoDB服务完成初始化并可接受连接。你的API容器启动时,MongoDB可能还在加载数据,导致10秒连接超时。

解决办法:

  • 在Golang代码中添加重试逻辑:替换直接panic的逻辑,循环尝试连接直到成功或达到最大重试次数:
    func NewMongoClient(conn string) *mongo.Client {
        var client *mongo.Client
        var err error
        maxRetries := 5
        retryDelay := 2 * time.Second
    
        for i := 0; i < maxRetries; i++ {
            client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://mongodb:27017"))
            if err != nil {
                time.Sleep(retryDelay)
                continue
            }
    
            ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
            defer cancel()
            err = client.Connect(ctx)
            if err != nil {
                time.Sleep(retryDelay)
                continue
            }
    
            err = client.Ping(ctx, nil)
            if err == nil {
                break // 连接成功,退出循环
            }
            time.Sleep(retryDelay)
        }
    
        if err != nil {
            panic("多次尝试后仍无法连接MongoDB: " + err.Error())
        }
        return client
    }
    
  • 给MongoDB添加健康检查:在docker-compose.yml中配置MongoDB的健康检查,让API容器仅在MongoDB服务就绪后启动:
    mongodb:
      image: mongo
      restart: unless-stopped
      container_name: mongodb
      ports:
        - "27017:27017"
      networks:
        - mongo-go
      volumes:
        - mongo-data:/var/lib/mongo01
      healthcheck:
        test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
        interval: 5s
        timeout: 5s
        retries: 5
    
    api:
      image: repo/image:latest
      container_name: api01
      restart: unless-stopped
      depends_on:
        mongodb:
          condition: service_healthy
      ports:
        - "3000:3000"
      networks:
        - mongo-go
    

3. 验证容器间的网络连通性

如果以上步骤无效,手动测试API容器与MongoDB容器的连通性:

  • 进入API容器内部:
    docker exec -it api01 sh
    
  • 执行以下命令排查:
    # 解析MongoDB主机名(应返回MongoDB容器的IP)
    nslookup mongodb
    # 测试网络连通性
    ping mongodb -c 3
    # 测试MongoDB端口是否可访问
    telnet mongodb 27017
    
    若无法解析或连通,说明网络配置异常,需重新创建mongo-go网络并重启所有容器。

4. 检查MongoDB的绑定配置

默认Docker官方Mongo镜像会绑定0.0.0.0(允许所有IP访问),但如果镜像有自定义配置,可能限制了访问范围。查看MongoDB容器日志确认:

docker logs mongodb

如果日志显示服务仅绑定到127.0.0.1,需在docker-compose.yml中添加启动参数修改绑定:

mongodb:
  image: mongo
  restart: unless-stopped
  container_name: mongodb
  command: mongod --bind_ip_all
  ports:
    - "27017:27017"
  networks:
    - mongo-go
  volumes:
    - mongo-data:/var/lib/mongo01

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:55:18