【问题标题】:docker-compose postgres dial error (dial tcp 172.23.0.3:5432: connect: connection refused)docker-compose postgres 拨号错误(dial tcp 172.23.0.3:5432: connect: connection refused)
【发布时间】:2023-01-10 08:11:42
【问题描述】:

我尝试从后端容器连接到 postgres 容器。 这是我的 docker-compose 文件:

version: "3.9"

services:
  imgress-producer:
    build:
      context: ./producer
      dockerfile: Dockerfile.producer
      target: prod
    container_name: imgress-producer
    ports:
      - 8080:8080
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
      - DATABASE_HOST=${DATABASE_HOST}
      - DATABASE_PORT=${DATABASE_PORT}
    depends_on:
      - imgress-db
    volumes:
      - ./:/app
    networks:
      - imgress-network

  imgress-db:
    image: postgres
    container_name: imgress-db
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
      - DATABASE_HOST=${DATABASE_HOST}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    ports:
      - 5432:5432
    networks:
      - imgress-network
    restart: always

volumes:
  postgres-data:

networks:
  imgress-network:
    driver: bridge

.env 文件:

POSTGRES_USER=postgres
POSTGRES_PASSWORD=root
POSTGRES_DB=imgress
DATABASE_HOST=imgress-db
DATABASE_PORT=5432

这是我尝试连接到数据库的方式:

package database

import (
    "fmt"
    "log"
    "os"
    "time"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

var GDB *gorm.DB

func ConnectDB() {
    var err error
    pgPort := os.Getenv("DATABASE_PORT")
    pgHost := os.Getenv("DATABASE_HOST")
    pgUser := os.Getenv("POSTGRES_USER")
    pgPassword := os.Getenv("POSTGRES_PASSWORD")
    pgName := os.Getenv("POSTGRES_DB")

    configData := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=disable",
        pgUser,
        pgPassword,
        pgHost,
        pgPort,
        pgName,
    )

    for i := 0; i < 5; i++ {
        GDB, err = gorm.Open(postgres.Open(configData), &gorm.Config{})
        if err == nil {
            break
        }
        time.Sleep(10 * time.Second)
    }
    if err != nil {
        log.Println("Producer: Error Connecting to Database")
    } else {
        log.Println("Producer: Connection Opened to Database")
    }
}

因此,在最后一部分,我重试直到数据库容器准备就绪。所以当数据库连接不成功时它应该记录一个错误。但相反,它无法连接并记录成功。

imgress-producer    | 2022/12/03 20:28:24 /go/pkg/mod/gorm.io/gorm@v1.24.1/gorm.go:206
imgress-producer    | [error] failed to initialize database, got error failed to connect to `host=imgress-db user=postgres database=imgress`: dial error (dial tcp 172.23.0.3:5432: connect: connection refused)
imgress-producer    | 2022/12/03 20:28:34 Producer: Connection Opened to Database

SO 上有很多连接被拒绝的相关问题,但没有一个对我有帮助。因此,我们将不胜感激任何形式的帮助。

【问题讨论】:

  • 您在循环中重试直到成功,而它确实成功了。那么问题是什么?
  • @jjanes 问题是错误信息
  • 在您收到成功消息之前,for 循环运行了多少次?确实看起来它在第一次尝试时连接失败,然后在第二次尝试时它通过并跳出循环。

标签: postgresql docker go docker-compose


【解决方案1】:

我稍微简化了您的代码,并且能够使其在我的机器上运行。让我们来看看它。回购结构是:

  1. .env
  2. docker-compose.yaml
  3. Dockerfile
  4. main.go

    让我们从main.go 文件开始。

    main.go

    package main
    
    import (
        "fmt"
        "log"
        "os"
        "time"
    
        "gorm.io/driver/postgres"
        "gorm.io/gorm"
    )
    
    var GDB *gorm.DB
    
    func ConnectDB() {
        var err error
        pgPort := os.Getenv("DATABASE_PORT")
        pgHost := os.Getenv("DATABASE_HOST")
        pgUser := os.Getenv("POSTGRES_USER")
        pgPassword := os.Getenv("POSTGRES_PASSWORD")
        pgName := os.Getenv("POSTGRES_DB")
    
        configData := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=disable",
            pgUser,
            pgPassword,
            pgHost,
            pgPort,
            pgName,
        )
    
        for i := 0; i < 5; i++ {
            GDB, err = gorm.Open(postgres.Open(configData), &gorm.Config{})
            if err == nil {
                break
            }
            time.Sleep(1 * time.Second) // change back to 10s
        }
        if err != nil {
            log.Println("Producer: Error Connecting to Database")
        } else {
            log.Println("Producer: Connection Opened to Database")
        }
    }
    
    func main() {
        ConnectDB()
    }
    

    这里没有相关的变化。

    .env

    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    POSTGRES_DB=postgres
    DATABASE_HOST=imgress-db
    DATABASE_PORT=5432
    

    这里也没什么好说的。

    Dockerfile

    FROM golang:1.19.3-alpine3.17 AS build
    WORKDIR /go/src/app
    COPY ./main.go ./main.go
    RUN go mod init pgdockercompose
    RUN go mod tidy
    RUN go build -o ./bin/webserver ./main.go
    
    FROM alpine:3.17
    COPY --from=build /go/src/app/bin /go/bin
    EXPOSE 8080
    ENTRYPOINT go/bin/webserver
    

    这里我们使用多阶段构建来构建和复制我们的 Go 程序。在 build 阶段,我们使用了一个更大的图像来初始化一个 go 模块,恢复依赖关系,并构建源代码。在更精简的图像中,我们复制构建过程的结果。

    docker-compose.yaml

    version: "3.9"
    
    services:
      imgress-producer:
        build: "."
        ports:
          - 8080:8080
        environment:
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=${POSTGRES_DB}
          - DATABASE_HOST=${DATABASE_HOST}
          - DATABASE_PORT=${DATABASE_PORT}
        depends_on:
          - imgress-db
        networks:
          - imgress-network
    
      imgress-db:
        image: postgres
        container_name: imgress-db
        environment:
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=${POSTGRES_DB}
          - DATABASE_HOST=${DATABASE_HOST}
        ports:
          - 5432:5432
        restart: always
        networks:
          - imgress-network
    
    networks:
      imgress-network:
        driver: bridge
    

    为了演示,我将省略卷。整合它们也不应该很痛苦。
    希望这可以澄清您的疑问!

【讨论】:

  • 你好,请问有消息了吗?你的问题解决了吗?
【解决方案2】:

解决方法。 如果你看过这里,我敢打赌你已经浏览过“将主机名从 localhost 更改为 DB”的日志。这些都不适合我。我已经浏览了 docker-compose 网络的所有文档,但它就是不起作用。这是解决方案

app:
 // other stuff
  - network_mode: "host"
db:
  - expose: 
    - "5432" // or the port you want

这会将您的数据库暴露给主机网络,您的应用程序将通过主机连接到您的数据库。不是很理想,但目前找到的最佳解决方案。如果有人有真正的解决方案并且自己尝试过。请告诉我。

【讨论】:

    猜你喜欢
    • 2022-12-30
    • 2023-01-31
    • 2021-05-04
    • 2021-04-12
    • 2022-12-17
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    相关资源
    最近更新 更多