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

Docker环境下Go Web服务连接MySQL容器报connection refused问题求助

问题修复方案

1. 核心错误1:容器内部网络端口使用错误

docker-compose中ports: "3307:3306"的规则是宿主机端口:容器内部端口,同Docker网络内的服务互相访问时,只能用容器内部监听的端口,而非宿主机映射端口。
需要修改main.go中的数据库连接地址:

// 错误写法
db, err := sql.Open("mysql", "user:password@tcp(db:3307)/example")
// 正确写法,额外补充parseTime参数是mysql驱动的强制要求,避免后续时间类型操作报错
db, err := sql.Open("mysql", "user:password@tcp(db:3306)/example?parseTime=true")

2. 核心错误2:服务启动顺序无依赖+MySQL初始化慢

MySQL容器首次启动需要执行初始化脚本、配置账号权限,耗时远长于Go服务启动,即使配置了depends_on也无法保证MySQL完全就绪后再启动Go服务。

修复方案:

  • 先修正docker-compose.yml的语法错误与依赖配置:
    version: '3'
    services:
      db:
        build:
          context: ./database
        volumes: 
          - database:/database/data
        environment:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: example
          MYSQL_USER: user
          MYSQL_PASSWORD: password
        container_name: container_db
        ports:
          - "3307:3306"
        networks:
          - default
        # 确认MySQL绑定所有地址,避免本地访问限制
        command: --bind-address=0.0.0.0
      api:
        build:
          context: .
        restart: on-failure
        container_name: "container_api"
        # 修正原配置中volumes缩进错误的问题
        volumes:
          - api:/usr/api
        ports:
          - "8080:8080"
        networks:
          - default
        # 增加服务依赖,保证先启动db再启动api
        depends_on:
          - db
    
    volumes:
        database:
        api:
    
  • 可选优化:在Go代码中增加数据库连接重试逻辑,避免首次启动MySQL未就绪导致的启动失败,示例:
    // 原db.Ping()部分替换为重试逻辑
    var pingErr error
    for i := 0; i < 10; i++ {
        pingErr = db.Ping()
        if pingErr == nil {
            break
        }
        log.Printf("数据库连接失败,2秒后重试,剩余重试次数:%d", 10 - i)
        time.Sleep(2 * time.Second)
    }
    if pingErr != nil {
        log.Fatal(pingErr)
    }
    
    记得导入time包。

3. 核心错误3:MySQL初始化SQL语法错误

example.sql中建表语句缺少逗号,会导致MySQL初始化失败、服务无法正常启动:

-- 错误写法
CREATE TABLE IF NOT EXISTS exampleTable (
    id           INT             NOT NULL,
    name         VARCHAR(2048)   NOT NULL,
    lastName     VARCHAR(2048)
    PRIMARY KEY (`id`)
);
-- 正确写法,lastName字段后补充逗号
CREATE TABLE IF NOT EXISTS exampleTable (
    id           INT             NOT NULL,
    name         VARCHAR(2048)   NOT NULL,
    lastName     VARCHAR(2048),
    PRIMARY KEY (`id`)
);

最终验证步骤

清理之前的错误容器与缓存卷,避免旧数据影响:

docker-compose down -v

重新构建启动服务:

docker-compose up --build

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:45:04