猿问

尝试在一个连接到另一个 postgres 的容器中运行 go 程序时出现拨号错误

我目前在我的 PC 上设置了两个 docker 容器,其中一个是使用 docker compose 创建的 PostgreSQL 容器,另一个包含用于初始化 PostgreSQL 数据库中的表的 go 代码。Docker compose 在创建容器/数据库方面非常有效(我将通过容器外部的 psql 登录它),并且 go 代码本身在容器外部正常运行(创建表)。当我尝试从自己的容器内运行代码时,无论我尝试连接到本地数据库还是容器化数据库,都会出现问题。这两种情况都会导致标题中的拨号错误。


我只是 docker 的初学者,所以我知道这很可能是我的问题,但这里是我的 dockerfile 的内容:


FROM golang:alpine AS builder 


#adding needed env variables 

ENV GO111MODULE=on \

    CGO_ENABLED=0 \

    GOOS=linux \

    GOARCH=amd64 

    

#move to /build 

WORKDIR /build 


#copy dependancies 

COPY go.mod . 

COPY go.sum . 

RUN go mod download 


#add code to container 

COPY . .


#build app 

RUN go build -o main . 


# Move to /dist directory as the place for resulting binary folder

WORKDIR /dist


# Copy binary from build to main folder

RUN cp /build/main .


# Build a small image

FROM scratch


COPY --from=builder /dist/main /


ENV DATABASE_URL=postgres://short:password@test:8001/shorturl

    #change database url variable to match your needs 

    

# Command to run

ENTRYPOINT ["/main"]

以及 docker-compose.yml 文件的内容:


version: '3'

services:

  database:

    container_name: test

    image: "postgres" # use latest official postgres version

    env_file:

      - ./db/database.env # configure postgres

    volumes:

      - database-data:/var/lib/postgresql/data/ # persist data even if container shuts down

    ports:

        - "8001:5432" 

  backend: 

    build: . 

volumes:

  database-data: 

代码本身存在于以下目录结构中:


/project/

    ./db/ 

         db.go 

         database.env

    main.go 

    go.mod 

    go.sum 

    Dockerfile 

    docker-compose.yml 

db.go 包含:


package db

import (

    "context"

    "fmt"

    "os"


    "github.com/jackc/pgx/v4/pgxpool"

)


正如我之前提到的,在任何容器之外运行所有这些都可以工作并填充数据库,并且 docker-compose 成功创建了一个我可以在本地连接到的 postgres 实例。


我不能做的是通过我的代码(在本地或在容器中运行)连接到容器化的 postgres,或者从我的代码的容器化版本连接到本地数据库。所有这些都会导致此错误的某些变化:


Unable to connect to database: failed to connect to `host=container_name user=short database=shorturl`: dial error (dial tcp 172.18.0.2:8001: connect: connection refused) 

我很好奇我在代码和/或 docker 中可能做错了什么,并希望有人可以最终运行它并重现我的问题/找出问题所在。


翻过高山走不出你
浏览 116回答 2
2回答

慕婉清6462132

我将尝试澄清 Michée Lengronne 所写的内容,我认为他的回答只是部分正确。你有两个容器 -test里面有 postgres 运行,一个未命名的里面有你的 go 应用程序,这个容器的名称是在每次容器启动时随机确定的。这两个容器都在同一个网络上。这很重要。ports使用 value定义时8001:5432,表示如果从定义的网络外部连接,并且选择端口8001进行连接,它将连接到5432内部的端口。但是,如果您仅从同一网络内连接,则可以省略定义ports并继续直接连接到test容器。意思是,使用带有默认端口 ( ) 的容器名称5432就足够了。TL; 博士DATABASE_URL=postgres://short:password@test:5432/shorturl

MMMHUHU

如果要连接到本地 postgres 或另一个 docker 网络中的 postgres,则必须在该变量中提供 postgres 的 IP 或域名:DATABASE_URL=postgres://short:password@test:8001/shorturl通常你应该替换test为localhost或127.0.0.1从错误中,您的应用程序尝试连接到172.18.0.2. 我想这个IP是来自postgres容器的IP。在此特定容器的 docker 网络之外无法访问它。如果您想通过此 IP 访问您的容器,您必须将您的应用程序容器添加到 postgres docker 网络。Docker 网络和撰写:https ://docs.docker.com/compose/networking/
随时随地看视频慕课网APP

相关分类

Go
我要回答