![](/img/trans.png)
[英]Golang + postgres + docker: Dial tcp 172.18.0.2: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 上有很多連接被拒絕的相關問題,但沒有一個對我有幫助。 因此,我們將不勝感激任何形式的幫助。
我稍微簡化了您的代碼,並且能夠在我的機器上運行它。 讓我們來看看它。 回購結構是:
.env
docker-compose.yaml
Dockerfile
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.