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

Go容器无法连接Postgres-alpine容器问题求助

Go容器连接Postgres-alpine容器失败问题排查与解决

问题详情

尝试将Go容器与postgres-alpine容器建立连接时失败,报错如下:

web_1 | [error] failed to initialize database, got error failed to connect to host=db user=postgres database=go: dial error (dial tcp 192.168.144.2:5432: connect: no route
to host)
web_1 | 2023/09/05 09:26:10 Failed to connect to database:
web_1 | failed to connect to host=db user=postgres database=go: dial error (dial tcp
192.168.144.2:5432: connect: no route to host)

使用.air.toml运行服务器,相关配置及代码如下:

docker-compose.yml

version: '3.7'

services:
   db : 
    image : postgres:alpine
    environment: 
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}
    ports :
      - 5432:5432
    volumes:
      - postgres-db:/var/lib/postgresql/data
  web : 
    build : .
    env_file : 
      - .env
    ports : 
      - 3000:3000
    depends_on : 
      - db 
    volumes : 
      - .:/usr/src/app
    command : air cmd/main.go -b 0.0.0.0

volumes:
  postgres-db:

数据库连接函数代码

func ConnectDb() {
dsn := fmt.Sprintf("host=db user=%s password=%s dbname=%s port=5432 sslmode=disable TimeZone=Asia/India",
    os.Getenv("DB_USER"),
    os.Getenv("DB_PASSWORD"),
    os.Getenv("DB_NAME"),
)

db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
    Logger: logger.Default.LogMode(logger.Info),
})

if err != nil {
    log.Fatal("Failed to connect to database: ", err)
    os.Exit(2)
}

log.Println("connected")
db.Logger = logger.Default.LogMode(logger.Info)

log.Println("running migrations")
db.AutoMigrate(&models.Facts{})

DB = Dbinstance{
    Db: db,
}
}

.env文件内容

DB_USER=postgres
DB_PASSWORD=root
DB_NAME=go

解决方案

1. 处理Postgres服务就绪延迟

depends_on仅保证db容器先启动,但Postgres服务可能还未完成初始化。可以通过两种方式解决:

方式一:添加启动等待脚本

修改docker-compose.yml中web服务的command,使用脚本等待Postgres端口就绪:

command: sh -c "wget -qO- https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh | sh -s -- db:5432 -t 30 -- air cmd/main.go -b 0.0.0.0"

方式二:在Go代码中添加重试逻辑

修改ConnectDb函数,增加连接重试机制:

import "time"

func ConnectDb() {
    var db *gorm.DB
    var err error
    maxRetries := 5
    retryDelay := 2 * time.Second

    for i := 0; i < maxRetries; i++ {
        dsn := fmt.Sprintf("host=db user=%s password=%s dbname=%s port=5432 sslmode=disable TimeZone=Asia/India",
            os.Getenv("DB_USER"),
            os.Getenv("DB_PASSWORD"),
            os.Getenv("DB_NAME"),
        )
        db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
            Logger: logger.Default.LogMode(logger.Info),
        })
        if err == nil {
            break
        }
        log.Printf("连接失败,%v后重试... (第%d/%d次尝试)", retryDelay, i+1, maxRetries)
        time.Sleep(retryDelay)
    }

    if err != nil {
        log.Fatal("多次尝试后仍无法连接数据库: ", err)
        os.Exit(2)
    }

    log.Println("连接成功")
    db.Logger = logger.Default.LogMode(logger.Info)
    log.Println("执行迁移")
    db.AutoMigrate(&models.Facts{})
    DB = Dbinstance{Db: db}
}

2. 验证Docker网络一致性

docker-compose默认会为服务创建专属网络,检查两个容器是否在同一网络:

docker inspect $(docker-compose ps -q web) | grep Networks
docker inspect $(docker-compose ps -q db) | grep Networks

若不在同一网络,删除现有容器和卷后重新构建:

docker-compose down -v
docker-compose up --build

3. 检查Postgres容器运行状态

查看Postgres容器日志,确认服务是否正常初始化:

docker-compose logs db

若日志显示权限等初始化错误,删除postgres-db卷后重新启动:

docker-compose down -v
docker-compose up

内容的提问来源于stack exchange,提问作者Venukishore.R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:18:57