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

Golang+Postgres+Docker部署:Dial tcp连接拒绝问题求助

使用Docker Compose部署Golang+Postgres时连接被拒绝的解决方案

问题分析

报错Dial tcp 172.18.0.2:5432: connect: connection refused的核心原因:

  • depends_on仅保证容器启动顺序,不确保Postgres服务完全就绪
  • 即使配置了healthcheck,默认情况下Golang应用容器不会等待数据库容器的健康检查通过就启动

修复步骤

1. 修改Docker Compose配置,让应用等待数据库就绪

更新docker-compose.yml中balance-app的depends_on配置,添加健康检查依赖条件:

version: '3.8'

services:
  balance-app:
    build: ./
    command: ./balance-app
    ports:
      - 8000:8000
    depends_on:
      db:
        condition: service_healthy # 等待db容器健康检查通过
    environment:
      - DB_PASSWORD=qwerty
      - DB_HOST=db


  db:
    restart: always
    image: postgres:latest
    volumes:
      - ./.database/postgres/data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=qwerty
    ports:
      - 5432
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres" ]
      interval: 3s
      timeout: 5s
      retries: 5 # 增加重试次数,确保数据库完全启动

2. 验证Golang配置加载逻辑

确保Viper正确读取配置文件,在数据库初始化代码前添加配置加载逻辑(如果未添加):

import (
    "log"
    "github.com/spf13/viper"
)

func init() {
    // 设置配置文件路径和格式
    viper.AddConfigPath(".")
    viper.SetConfigName("config")
    viper.SetConfigType("yaml")
    
    if err := viper.ReadInConfig(); err != nil {
        log.Fatalf("Failed to load config: %v", err)
    }
}

另外,检查数据库端口是否需要转换为整数(部分Postgres驱动要求端口为int类型):

import "strconv"

// ...

portStr := viper.GetString("db.port")
port, err := strconv.Atoi(portStr)
if err != nil {
    log.Fatalf("Invalid DB port: %v", err)
}

db, err := repository.NewPostgresDB(repository.Config{
    Host:     os.Getenv("DB_HOST"),
    Port:     port, // 使用int类型端口
    Username: viper.GetString("db.username"),
    DBName:   viper.GetString("db.dbname"),
    SSLMode:  viper.GetString("db.sslmode"),
    Password: os.Getenv("DB_PASSWORD"),
})

3. 添加数据库连接重试逻辑

在应用初始化时添加重试机制,应对偶发的启动延迟:

import (
    "log"
    "time"
)

func main() {
    var db *sql.DB
    var err error
    maxRetries := 5

    for i := 0; i < maxRetries; i++ {
        db, err = repository.NewPostgresDB(repository.Config{
            Host:     os.Getenv("DB_HOST"),
            Port:     viper.GetString("db.port"),
            Username: viper.GetString("db.username"),
            DBName:   viper.GetString("db.dbname"),
            SSLMode:  viper.GetString("db.sslmode"),
            Password: os.Getenv("DB_PASSWORD"),
        })
        if err == nil {
            log.Println("Successfully connected to database")
            break
        }
        log.Printf("Connection attempt %d failed: %v. Retrying in 2s...", i+1, err)
        time.Sleep(2 * time.Second)
    }

    if err != nil {
        log.Fatalf("Failed to connect to database after %d retries: %v", maxRetries, err)
    }

    // 后续应用逻辑...
}

4. 验证数据库容器状态

运行以下命令检查数据库容器的健康状态:

docker-compose ps

确保db容器的状态为healthy。也可以查看日志确认健康检查是否正常:

docker-compose logs db

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:15:42