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

Docker Compose下Golang API无法连接PostgreSQL求助

问题分析

从日志时间线可明确问题根源:

  • Go服务在22:51:23尝试连接PostgreSQL,但PostgreSQL在22:51:24才开始监听端口,此时数据库尚未就绪,导致连接被拒绝。
  • 重启容器时PostgreSQL已处于运行就绪状态,因此Go服务能正常连接。
解决方案

1. 配置Docker Compose依赖与健康检查

默认的depends_on仅保证容器启动顺序,无法确保服务就绪。需给PostgreSQL添加健康检查,让Go服务等待数据库完全就绪后再启动:

修改docker-compose.yml:

version: "3.7"
services:
  gobank:
    build: .
    container_name: gobank
    env_file:
      - .env
    ports:
      - 3000:3000
    command: make run
    extra_hosts:
      - "host.docker.internal:host-gateway"
    depends_on:
      db:
        condition: service_healthy # 等待db健康检查通过

  db:
    image: postgres:16
    container_name: postgres
    environment:
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_DB=gobank
    ports:
      - 5432:5432
    extra_hosts:
      - "host.docker.internal:host-gateway"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d gobank"]
      interval: 2s
      timeout: 5s
      retries: 5 # 最多重试5次,每次间隔2秒

2. 在Go代码中添加连接重试逻辑

即使配置了Docker健康检查,仍可能存在网络波动或服务启动延迟,在代码层面添加重连逻辑可彻底规避此类问题:

示例代码:

import (
	"database/sql"
	"fmt"
	"time"

	_ "github.com/lib/pq"
)

func connectDB(user, dbname, password string) (*sql.DB, error) {
	connStr := fmt.Sprintf("host=db port=5432 user=%s dbname=%s password=%s sslmode=disable", user, dbname, password)
	var db *sql.DB
	var err error

	// 最多重试5次,每次间隔3秒
	for i := 0; i < 5; i++ {
		db, err = sql.Open("postgres", connStr)
		if err == nil {
			// 验证连接是否有效
			if err = db.Ping(); err == nil {
				break
			}
		}
		fmt.Printf("连接数据库失败,%d秒后重试...\n", 3)
		time.Sleep(3 * time.Second)
	}
	return db, err
}

3. 临时方案:手动控制启动顺序

若不想修改配置和代码,可先单独启动PostgreSQL容器,确认其就绪后再启动Go服务:

# 先启动db服务
docker-compose up -d db
# 等待几秒确认数据库就绪后,启动gobank
docker-compose up gobank

内容的提问来源于stack exchange,提问作者Leonardo Alipazaga Bazan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:40:09