【问题标题】:Can't connect to Postgres docker container from Golang container无法从 Golang 容器连接到 Postgres docker 容器
【发布时间】:2020-02-24 04:29:31
【问题描述】:

我有一个使用 golang 构建的 Web 服务器。当我在本地测试它时它可以成功。

但是,当我为我的 Web 服务器构建 docker 映像时,它无法连接到正在运行的 Postgres 容器。

这是我的docker-compose.yml

version: '2'
services:
    go:
        image: golang:1.7
        volumes:
          - ./:/server/http
        ports:
            - "80:8080"
        links:
            - postgres
            - mongodb
            - redis
        environment:
            DEBUG: 'true'
            PORT: '8080'

    postgres:
        image: onjin/alpine-postgres:9.5
        restart: unless-stopped
        ports:
            - "5432:5432"
        environment:
            LC_ALL: C.UTF-8
            POSTGRES_USER: user
            POSTGRES_PASSWORD: pass
            POSTGRES_DB: mydb
    mongodb:
        image: mvertes/alpine-mongo:3.2.3
        restart: unless-stopped
        ports:
            - "27017:27017"

    redis:
        image: sickp/alpine-redis:3.2.2
        restart: unless-stopped
        ports:
            - "6379:6379"

我的Dockerfile

FROM golang:1.7

RUN mkdir -p /home/app

WORKDIR /home/app

COPY . /home/app

RUN make deps && make

ENTRYPOINT ["./bin/api-test"]

EXPOSE 8080

我正在使用的 Postgres 连接字符串:

postgresql://user:pass@host/mydb?sslmode=disable

对于主机,我尝试了localhost,它返回以下错误:

dial tcp [::1]:5432: getsockopt: connection refused

尝试postgres 并返回以下内容:

dial tcp 202.71.99.194:5432: getsockopt: connection refused

尝试了运行此命令的 IP 地址,该命令返回 172.19.0.3

docker inspect apitest_postgres_1 | grep IPAddress

apitest_postgres_1 是 Postgres 容器名称。它也返回了这个错误:

dial tcp 172.19.0.3:5432: getsockopt: connection timed out

你能告诉我我在这里缺少什么吗?我对 docker 缺乏经验,这需要很长时间才能找到解决方案。

编辑: 我使用以下命令运行我的 golang docker:

docker run --env-file ./example.env --rm -it -p 8080:8080  api-test

example.env 是包含我的环境变量的文件。

编辑 2: 我将连接字符串更改为以下内容:

postgresql://user:pass@postgres:5432?sslmode=disable

它返回以下错误:

dial tcp: lookup postgres on 192.168.65.1:53: no such host

我的想法是我的 Mac 是这里的问题。我的默认 DNS 是 8.8.8.8,这应该不是问题。

【问题讨论】:

  • 您是否尝试过将postgres 设置为网址postgresql://user:secret@postgres/mydb?sslmode=disable 中的主机?与服务名称相同。
  • @Зелёный yup 试过了,它返回以下错误:dial tcp 202.71.99.194:5432: getsockopt: connection refused
  • 您确定在 Postgres pg_hba.conf 中允许通过 TCP/IP 网络进行所有连接吗?
  • @Зелёный 这就是解决方案!但是如何为下载的 docker 容器修改pg_hba.conf?我无法运行 docker exec -it apitest_postgres_1 bash 来更改它。
  • 你可以扩展基础镜像,做你想做的事。给我一些时间,我会用 Dockerfile 发布答案。

标签: postgresql docker


【解决方案1】:

看起来你是在拉去图像而不是构建你自己的图像。

build: . 代替image: golang:1.7 来构建和使用您的Dockerfile

您可能还需要传递 postgres 环境变量 DB_HOSTDB_USERDB_PASS 等。您可以实现这一点,但创建例如 docker.env 文件,然后在您的 go 应用程序 docker-compose.yml 下添加 env_file文件:

docker.env 示例:

DB_HOST=postgres
DB_USER=user
DB_PASS=pass
DB_NAME=mydb

更正 docker-compose.yml :

version: '2'
services:
    app:
        build: .
        volumes:
          - ./:/server/http
        ports:
            - "80:8080"
        links:
            - postgres
            - mongodb
            - redis
        environment:
            DEBUG: 'true'
            PORT: '8080'
        env_file: 
          - docker.env

    postgres:
        image: onjin/alpine-postgres:9.5
        restart: unless-stopped
        ports:
            - "5432:5432"
        environment:
            LC_ALL: C.UTF-8
            POSTGRES_USER: user
            POSTGRES_PASSWORD: pass
            POSTGRES_DB: mydb

    mongodb:
        image: mvertes/alpine-mongo:3.2.3
        restart: unless-stopped
        ports:
            - "27017:27017"

    redis:
        image: sickp/alpine-redis:3.2.2
        restart: unless-stopped
        ports:
            - "6379:6379"

【讨论】:

    【解决方案2】:

    为了在 docker compose 中建立与 postgres 的连接,您需要将 localhost127.0.0.1postgres 替换为您的连接字符串与您的 docker compose 文件中提到的容器名称。

    例如,在您的 docker-compose.yaml 文件中创建这样的数据库:

    db:
        container_name: composepostgres
        image: postgres
        environment:
    

    然后,在您的代码中创建连接字符串时,避免使用127.0.0.1localhostpostgres,而是使用composepostgres 代替它们。

    如果不这样做,您将面临dial tcp 127.0.0.1:5432: connect: connection refused 错误。

    【讨论】:

      【解决方案3】:

      看看这个文档:https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/

      然后,关于 docker-compose 文件中的链接,将连接字符串中的“host”替换为“postgres”:

      postgresql://user:pass@postgres/mydb?sslmode=disable
      

      让嵌入式 DNS 服务器完成映射工作,因为每次重新创建容器时 IP 地址都可能发生变化。

      另外,确保 postgres 允许连接(可能仅限于本地主机)

      【讨论】:

        猜你喜欢
        • 2017-06-06
        • 2020-11-20
        • 1970-01-01
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 2020-06-06
        相关资源
        最近更新 更多