5

I have a linux postgres database running on my localhost at port 5432. The IP of my machines network card is 192.168.68.80. My configuration files for postgres look as so:

/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

Now I want to connect to this database from a Node application running inside a docker container. This is what my environment variables file looks like when loading into Node:

.env

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

After this setup, I build my docker image using my docker file. I then try to run the dockerfile as a container with the following command on linux:

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

and the app begins to run, and listens for connections on port 3000. But whenever I try to connect to the app, the app fails to connect to the postgres database server and gives the following error:

/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
  }
}

I can not figure out why the connection is being refused as it seems like it should be able to connect.

EDIT:

My current ip tables in case that helps:

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
nick2225
  • 527
  • 5
  • 17

2 Answers2

1

docker has its own network within the container. When you say "PGHOST=localhost", it will connect to docker container's internal localhost (which has no relation with your machine localhost), not your machine localhost. You have to put a same network in which your docker and machine is running. It can be your network IP. You can get the IP by giving command "ip a" in linux. In my case my wifi is the common network, which ip is "192.168.X.X/24" giving "192.168.X.X" instead of "localhost" will work for me.

Sajjad
  • 11
  • 2
  • If I pass the argument --network="host", shouldn't that make Docker point to my localhost as well? Is that not the correct use of that docker run argument? – nick2225 Jun 29 '21 at 07:02
  • Also I changed PGHOST=192.168.68.80, the IP of my machine's network card, and am still getting a connection refused. – nick2225 Jun 29 '21 at 07:08
  • Can you try with --network=host. I just tried with my app. It worked. – Sajjad Jun 29 '21 at 07:36
0

From a container, the IP address of the host machine is 172.17.0.1. So you should connect to 172.17.0.1:5432.

Hans Kilian
  • 18,948
  • 1
  • 26
  • 35
  • When I change PGHOST=172.17.0.1, I still get the same connection refused error: connect ECONNREFUSED 172.17.0.1:5432. – nick2225 Jun 29 '21 at 07:06
  • @nick2225 Ye.. I've seen a lot of folks point to that solution, but I'm also getting a refused connection. The postgres is set up by default (0.0.0.0:5432 5432/tcp), so it shouldnt be something within postgres that refuses the gateway. :/ – FlushNorris Feb 20 '22 at 09:46