Docker Compose部署Go API连接MySQL时遇连接拒绝问题求助
解决Go API连接Docker MySQL容器时的连接拒绝问题
问题描述
错误信息:
dial tcp 192.168.48.2:3306: connect: connection refused
Go API连接数据库时持续被拒绝,已确认端口及参数配置匹配,尝试过修改端口、使用root用户连接,问题仍未解决。相关配置及代码如下:
Docker Compose配置
services: db: image: mysql:8.0 platform: linux/amd64 container_name: mysql_container environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: dbname MYSQL_USER: user MYSQL_PASSWORD: user_password expose: - "3306" volumes: - mysql-data:/var/lib/mysql playgobackend: build: context: . dockerfile: ./cmd/main/Dockerfile container_name: playgobackend ports: - "8080:8080" depends_on: - db environment: DB_HOST: db DB_PORT: 3306 DB_USER: user DB_PASSWORD: user_password DB_NAME: dbname volumes: mysql-data: networks: default:
Go API数据库连接代码
var ( db *gorm.DB ) func Connect() { dsn := "user:user_password@tcp(db:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" d, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } db = d }
解决方法
1. 确保MySQL服务完全就绪
depends_on仅保证容器启动顺序,不代表MySQL服务已完成初始化。给db服务添加健康检查,确保服务就绪后再启动Go API:
db: # 保留原有配置 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "user", "-puser_password"] interval: 5s timeout: 5s retries: 5 playgobackend: # 保留原有配置 depends_on: db: condition: service_healthy
2. 修改MySQL绑定地址
MySQL默认可能仅绑定127.0.0.1,导致同一Docker网络内的其他容器无法连接。在db服务中添加启动命令,让MySQL绑定所有地址:
db: # 保留原有配置 command: --bind-address=0.0.0.0
3. 检查数据库用户权限
确认user用户允许从任意主机连接(而非仅localhost):
- 进入MySQL容器:
docker exec -it mysql_container mysql -uroot -ppassword
- 执行授权SQL:
GRANT ALL PRIVILEGES ON dbname.* TO 'user'@'%'; FLUSH PRIVILEGES;
4. 改用环境变量读取DSN
避免硬编码配置导致的不一致,从环境变量中读取数据库参数:
import ( "fmt" "os" "gorm.io/driver/mysql" "gorm.io/gorm" ) var ( db *gorm.DB ) func Connect() { host := os.Getenv("DB_HOST") port := os.Getenv("DB_PORT") user := os.Getenv("DB_USER") password := os.Getenv("DB_PASSWORD") dbName := os.Getenv("DB_NAME") dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, host, port, dbName) d, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic(err) } db = d }
5. 测试容器间网络连通性
进入Go API容器,验证与db容器的网络连通性:
# 测试ping是否通 docker exec -it playgobackend ping db # 测试3306端口是否可访问 docker exec -it playgobackend telnet db 3306
如果ping不通,检查Docker默认网络配置;如果telnet不通,回到前序步骤排查MySQL绑定地址和服务状态。
内容的提问来源于stack exchange,提问作者Whoisshaggy
相关产品推荐
相关产品推荐

