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

Docker中PostgreSQL无法通过pgadmin、psql及Golang应用连接的问题

问题排查:Golang API Docker容器连接PostgreSQL失败及本地认证问题

遇到的两类问题

  1. 本地通过pgAdmin/psql连接PostgreSQL容器时,提示password authentication failed for user postgres;尝试进入PostgreSQL容器时,出现the input device is not a TTY,移除-ti参数后无有效反馈。
  2. Golang应用连接数据库失败,日志显示dial tcp 172.29.0.2:5432: connect: connection refused。

现有配置文件

docker-compose.yml

version: '3.8'
services:
  go_db:
    container_name: go_db
    image: postgres:12
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: apploggerstorage
    ports:
      - 5432:5432
    volumes:
      - pgdata:/var/lib/postgresql/data
  app_logger:
    container_name: app_logger
    image: lanceguinto/app_logger:1.0.0
    build: .
    environment:
      DATABASE_URL: "host=go_db user=postgres password=postgres dbname=apploggerstorage sslmode=disable"
    ports:
      - 8000:8000
    depends_on:
      - go_db
volumes:
  pgdata:

(注:原配置遗漏顶层volumes声明,已补充)

Dockerfile

FROM golang:1.21.6
WORKDIR /app
COPY . .
RUN go get -d -v ./...
RUN go build -o applogreader .
EXPOSE 8000
CMD ["./applogreader"]

补充说明

  • Golang应用代码存于外部粘贴板
  • 参考某YouTube教程搭建

问题排查与解决方案

针对问题1:本地认证失败+容器进入异常

  1. 修复容器进入异常:
    进入PostgreSQL容器的正确命令:

    docker exec -it go_db bash
    

    Windows环境若仍提示input device is not a TTY,尝试:

    winpty docker exec -it go_db bash
    

    进入容器后,用内置psql验证账号有效性:

    psql -U postgres -d apploggerstorage
    

    输入密码postgres,若能成功进入,说明容器内账号配置正常,问题出在本地连接环节。

  2. 排查本地认证失败:

    • 检查本地是否有其他进程占用5432端口:
      # Linux/macOS
      lsof -i :5432
      # Windows
      netstat -ano | findstr :5432
      
      若有占用,可停止该进程,或修改docker-compose中PostgreSQL的端口映射为5433:5432,本地连接时改用5433端口。
    • 本地连接时,确保主机填localhost、端口用映射后的值(默认5432)、用户名postgres、密码postgres、数据库apploggerstorage。
    • 若之前启动过容器,pgdata卷可能留存旧认证信息,删除卷重新构建:
      docker-compose down -v
      docker-compose up -d
      

针对问题2:Golang应用连接被拒绝

  1. 解决容器启动顺序问题:
    depends_on仅保证go_db容器先启动,但不确保PostgreSQL服务完全就绪,Golang应用启动时数据库可能仍在初始化。
    两种解决方式:

    • 在Golang代码中添加连接重试逻辑:
      import (
        "log"
        "os"
        "time"
        "database/sql"
        _ "github.com/lib/pq"
      )
      
      func initDB() *sql.DB {
          var db *sql.DB
          var err error
          maxRetries := 10
          for i := 0; i < maxRetries; i++ {
              db, err = sql.Open("postgres", os.Getenv("DATABASE_URL"))
              if err == nil {
                  err = db.Ping()
                  if err == nil {
                      break
                  }
              }
              time.Sleep(1 * time.Second)
          }
          if err != nil {
              log.Fatalf("Failed to connect to database after %d retries: %v", maxRetries, err)
          }
          return db
      }
      
    • 在docker-compose中添加健康检查,确保PostgreSQL就绪后再启动Golang应用:
      修改go_db服务配置:
      go_db:
        # ... 原有配置 ...
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U postgres -d apploggerstorage"]
          interval: 5s
          timeout: 5s
          retries: 5
      
      修改app_logger服务的depends_on:
      app_logger:
        # ... 原有配置 ...
        depends_on:
          go_db:
            condition: service_healthy
      
  2. 验证容器间网络连通性:
    进入Golang应用容器,尝试ping go_db:

    docker exec -it app_logger ping go_db
    

    若能ping通,再尝试用psql连接数据库:

    docker exec -it app_logger psql -U postgres -d apploggerstorage -h go_db
    

    若连接失败,查看PostgreSQL容器日志排查初始化问题:

    docker logs go_db
    
  3. 检查环境变量注入是否正确:
    进入Golang容器查看DATABASE_URL是否正确:

    docker exec -it app_logger printenv DATABASE_URL
    

    确认内容为host=go_db user=postgres password=postgres dbname=apploggerstorage sslmode=disable,若不符,检查docker-compose中环境变量的拼写。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:03:27