Docker环境下Go容器无法连接MySQL容器的问题求助
Docker环境下Go服务无法连接MySQL的解决方案
问题核心
本地运行Go程序能正常连接MySQL容器,但通过Docker Compose部署Go服务后,无法建立数据库连接。这是因为Docker容器网络规则、服务初始化顺序以及硬编码配置导致的典型问题。
解决方案步骤
1. 修正数据库连接地址(核心问题)
Docker Compose中,同一网络内的容器可以通过服务名直接访问,而不是localhost或主机端口:
- 不要用
localhost:3312(这是主机映射的端口,容器内部无法通过localhost访问主机) - 改用docker-compose中定义的MySQL服务名
mysql,端口用容器内部的3306(不是主机映射的3312)
同时,禁止硬编码连接信息,改用环境变量从.env读取,保证配置灵活性:
修改Go连接代码:
package configs import ( "fmt" "os" "time" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) func LoadConDB() (*sqlx.DB, error) { // 从环境变量读取配置 dbUser := os.Getenv("DB_USER") dbPass := os.Getenv("DB_PASSWORD") dbHost := os.Getenv("DB_HOST") dbPort := os.Getenv("DB_PORT") dbName := os.Getenv("DB_NAME") // 构建DSN字符串 dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true", dbUser, dbPass, dbHost, dbPort, dbName) var db *sqlx.DB var err error // 添加重试逻辑(应对MySQL初始化延迟) for retry := 0; retry < 5; retry++ { db, err = sqlx.Connect("mysql", dsn) if err == nil { break } time.Sleep(2 * time.Second) } if err != nil { return nil, fmt.Errorf("数据库连接失败: %w", err) } return db, nil }
在.env文件中添加对应配置:
DB_USER=root DB_PASSWORD=root DB_HOST=mysql # 对应docker-compose中的mysql服务名 DB_PORT=3306 DB_NAME=zumenu_db
2. 处理MySQL初始化延迟
depends_on仅保证MySQL容器先启动,但不代表MySQL服务已经完成初始化并可以接受连接。上面代码中添加的5次重试(每次间隔2秒),可以有效避免Go服务在MySQL就绪前发起连接导致的失败。
3. 确认Docker Compose配置细节
- 确保两个服务都加入了同一个网络
zumenu-network(你的配置已满足) - 确认Go服务的
env_file配置正确,保证环境变量能被容器读取 - 检查MySQL容器的环境变量是否正确引用了
.env中的值(你的配置已满足)
4. 验证MySQL容器状态
启动后可以通过以下命令查看MySQL是否正常初始化:
docker logs mysql-zumenu-backoffice
确认日志中出现ready for connections字样,说明MySQL服务已就绪。
内容的提问来源于stack exchange,提问作者André Martins
相关产品推荐
相关产品推荐

