【问题标题】:Connecting to a localhost postgres database from within a docker container [duplicate]从 docker 容器中连接到 localhost postgres 数据库[重复]
【发布时间】:2021-09-11 08:47:08
【问题描述】:

我有一个 linux postgres 数据库在我的 localhost 上的 5432 端口上运行。我的机器网卡的 IP 是 192.168.68.80。我的 postgres 配置文件如下所示:

/etc/postgresql/13/main/postgresql.conf

listen_addresses = '*'

/etc/postgresql/13/main/pg_hba.conf

host    all             all             0.0.0.0/0               md5
host    all             all             ::/0                    md5

现在我想从在 docker 容器中运行的 Node 应用程序连接到这个数据库。这是我的环境变量文件加载到 Node 时的样子:

.env

PGHOST=localhost // Host of the postgres db server
PGPORT=5432 // Port of the postgres db

完成此设置后,我使用我的 docker 文件构建我的 docker 映像。然后我尝试在 linux 上使用以下命令将 dockerfile 作为容器运行:

sudo docker run --network="host" --env-file .env -p 3000:3000 repo:tag

应用程序开始运行,并在端口 3000 上侦听连接。但每当我尝试连接到应用程序时,应用程序无法连接到 postgres 数据库服务器并给出以下错误:

/node_modules/sequelize/lib/dialects/postgres/connection-manager.js:172
                reject(new sequelizeErrors.ConnectionRefusedError(err));
                       ^

ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:5432
    at Client._connectionCallback (/node_modules/sequelize/lib/dialects/postgres/connection-manager.js:172:24)
    at Client._handleErrorWhileConnecting (/node_modules/pg/lib/client.js:305:19)
    at Client._handleErrorEvent (/node_modules/pg/lib/client.js:315:19)
    at Connection.emit (node:events:394:28)
    at Socket.reportStreamError (/node_modules/pg/lib/connection.js:52:12)
    at Socket.emit (node:events:394:28)
    at emitErrorNT (node:internal/streams/destroy:193:8)
    at emitErrorCloseNT (node:internal/streams/destroy:158:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  parent: Error: connect ECONNREFUSED 127.0.0.1:5432
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16) {
    errno: -111,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 5432
  },
  original: Error: connect ECONNREFUSED 127.0.0.1:5432
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16) {
    errno: -111,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 5432
  }
}

我无法弄清楚为什么连接被拒绝,因为它似乎应该能够连接。

编辑:

我当前的 ip 表以防万一:

user$ sudo iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (2 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere

【问题讨论】:

    标签: node.js postgresql docker networking


    【解决方案1】:

    docker 在容器中拥有自己的网络。当您说 "PGHOST=localhost" 时,它将连接到 docker 容器的内部 localhost(与您的机器 localhost 无关),而不是您的机器 localhost。您必须将您的 docker 和机器运行在同一个网络中。它可以是您的网络 IP。您可以通过在 linux 中给出命令 "ip a" 来获取 IP。在我的情况下,我的 wifi 是公共网络,ip 是 "192.168.XX/24" 给出 "192.168.XX" 而不是 "localhost" 对我有用。

    【讨论】:

    • 如果我传递参数--network="host",那不应该让Docker也指向我的本地主机吗?这不是正确使用 docker run 参数吗?
    • 另外我更改了PGHOST=192.168.68.80,我机器网卡的IP,但连接仍然被拒绝。
    • 你可以试试 --network=host.我刚刚尝试了我的应用程序。它奏效了。
    【解决方案2】:

    从容器中,主机的 IP 地址是 172.17.0.1。所以你应该连接到172.17.0.1:5432

    【讨论】:

    • 当我更改 PGHOST=172.17.0.1 时,我仍然收到相同的连接被拒绝错误:connect ECONNREFUSED 172.17.0.1:5432。
    猜你喜欢
    • 2023-04-02
    • 2020-04-27
    • 1970-01-01
    • 2019-11-11
    • 2022-11-12
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多