簡體   English   中英

docker-compose postgres dial error (dial tcp 172.23.0.3:5432: connect: connection refused)

[英]docker-compose postgres dial error (dial tcp 172.23.0.3:5432: connect: connection refused)

我嘗試從后端容器連接到 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 上有很多連接被拒絕的相關問題,但沒有一個對我有幫助。 因此,我們將不勝感激任何形式的幫助。

我稍微簡化了您的代碼,並且能夠在我的機器上運行它。 讓我們來看看它。 回購結構是:

  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

為了演示,我將省略卷。 整合它們也不應該很痛苦。
希望這可以澄清您的疑問!

解決方法。 如果你看過這里,我敢打賭你已經瀏覽過“將主機名從 localhost 更改為 DB”的日志。 這些都不適合我。 我已經閱讀了 docker-compose.network 的所有文檔,但它不起作用。 這是解決方案

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

這會將您的數據庫暴露給主機。網絡,您的應用程序將通過主機連接到您的數據庫。 不是很理想,但目前找到的最佳解決方案。 如果有人有真正的解決方案並且自己嘗試過。 請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM