从 docker 容器内连接到本地主机 postgres 数据库

时间:2021-06-29 06:31:34

标签: node.js postgresql docker networking

我有一个 linux postgres 数据库在我的本地主机上运行,​​端口为 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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

从一个容器来看,宿主机的IP地址是172.17.0.1。所以你应该连接到 172.17.0.1:5432