Dockerizing PostgreSQL - psql Connection refused - postgresql

I'm playing around with Docker and I would like to Dockerize a Postgres container.
I'm following the official example but I can not connect to the image running using psql.
I created the Dockerfile with the content of the example. I builded an image from the Dockerfile and assigned it a name. Then I run the PostgreSQL server container (in the foreground).
~/test » docker run --rm -P --name pg_test eg_postgresql
2014-10-10 06:12:43 UTC LOG: database system was interrupted; last known up at 2014-10-10 06:12:29 UTC
2014-10-10 06:12:43 UTC LOG: database system was not properly shut down; automatic recovery in progress
2014-10-10 06:12:43 UTC LOG: redo starts at 0/1782F68
2014-10-10 06:12:43 UTC LOG: record with zero length at 0/1782FA8
2014-10-10 06:12:43 UTC LOG: redo done at 0/1782F68
2014-10-10 06:12:43 UTC LOG: last completed transaction was at log time 2014-10-10 06:12:29.2487+00
2014-10-10 06:12:43 UTC LOG: database system is ready to accept connections
2014-10-10 06:12:43 UTC LOG: autovacuum launcher started
Then I open another terminal to find out the port:
~/test » docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aaedb0479139 eg_postgresql:latest "/usr/lib/postgresql 3 days ago Up 41 seconds 0.0.0.0:49154->5432/tcp pg_test
So I can use psql to connect to the instance. But I can't...
~/test » psql -h localhost -p 49154 -d docker -U docker --password
Password for user docker:
psql: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 49154?
could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 49154?
could not connect to server: Connection refused
Is the server running on host "localhost" (fe80::1) and accepting
TCP/IP connections on port 49154?
Any help is appreciated.

Solution for me was simply using host.docker.internal instead of localhost in your connection string.
https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/225

If you add the --publish option to the docker run command
docker run --rm -P --publish 127.0.0.1:5432:5432 --name pg_test eg_postgresql
when you run the docker file, then the following will work (note the port is now 5432)
psql -h localhost -p 5432 -d docker -U docker --password

Running this on my mac worked for me:
$ boot2docker ip
The VM's Host only interface IP address is: 192.168.59.103
And then connect along the lines of:
$ psql -h 192.168.59.103 -p 49159 -d docker -U docker --password
It's less than ideal to have to do this all, but the instructions at https://docs.docker.com/installation/mac/ indicate it is the correct solution if you want to connect directly from you mac.

To get IP address of your running container you can:
docker inspect pg_test | grep IPAddress
and then use it instead of 'localhost'.
Where pg_test is container name received from
docker ps

Someone has answered to this question here
To sum up : It is not enough to publish the container's port because on OS x the docker containers are running on virtual machines.
To retrieve the "real" address of the virtual machine you should use the tool which is managing your docker daemon and containers.
I would recommand to use docker-machine
The logic is very similar to wf answer but instead of using boot2docker it uses docker-machine.
1-/ Retrieve the name of the virtual machine
docker-machine ls
2-/ Retrieve the IP Address of the virtual machine by using its name e.g, default
docker-machine ip default
3-/ Use this value wherever you need to specify an host value.

Related

SSH to docker container that refuse to start

My spring boot app is connecting to postgres and I want to set /etc/hosts like in add-postgres-port-hosts but my container refusing to run when I try to run it using docker run -d -p 8080:8080 springio/flyaway-postgres it fails to run in the background because it tries to find localhost inside the container -
Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections
So how can I run docker exec [container] nc -v -z localhost 5432 in a container that I cannot run in detach mode?
Thank you.

Postgres won't start after reboot on Linux

I am running postgres 12 and it won't start after server reboot (run manually by reboot). The attached EBS volume has not changed and I don't see any evidence of a data loss.
When I run psql, I get (this used to work before restart)
psql -h localhost -U postgres
psql: error: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
pg_lsclusters does not help -
pg_lsclusters 12 main start
Ver Cluster Port Status Owner Data directory Log file
12 main 5432 down postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
The error in /var/log/postgresql/postgresql-12-main.log is
pg_ctl: could not start server
Examine the log output.
2021-03-01 00:33:24.976 UTC [1866] FATAL: could not access file "anon": No such file or directory
2021-03-01 00:33:24.976 UTC [1866] LOG: database system is shut down
When I start postgres, I don't get any error -
sudo service postgresql start
If you don’t want to start PostgreSQL manually every time your Linux restarts, run the following command :
sudo update-rc.d postgresql enable
If it can not find LSB script then do this :
sudo systemctl enable postgresql

How do I connect to a Postgresql set up on docker, running on local host, with dbeaver?

I am running a postgresql database on docker, hosting it on my local machine. When I try and connect to it using DBeaver though, I am given the error:
Connection to localhost:5432 refused.
Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
Connection refused: connect
Here are the commands I ran in Docker to create my PostgreSQL image:
rrowe#LAPTOP-AFM43BOB MINGW64 /c/Program Files/Docker Toolbox
$ docker run --name RiohRoweDB -e POSTGRES_PASSWORD=Charlie -d -p 5432:5432 postgres
55c78d059fdb2b19bfdd24f579eaf26ef5b00c77ead564ee7d128fd06996789d
rrowe#LAPTOP-AFM43BOB MINGW64 /c/Program Files/Docker Toolbox
$ docker exec -it RiohRoweDB bash
root#55c78d059fdb:/# psql -U postgres
psql (12.0 (Debian 12.0-2.pgdg100+1))
Type "help" for help.
postgres=# CREATE DATABASE postgresqlDB
postgres-# \q
root#55c78d059fdb:/# exit
exit
rrowe#LAPTOP-AFM43BOB MINGW64 /c/Program Files/Docker Toolbox
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55c78d059fdb postgres "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:5432->5432/tcp RiohRoweDB
On the DBeaver side, I add a connection with the following parameters:
Host:localhost
Port:5432
Database:postgresqlDB
User:postgres
Password:Charlie
When I test the connection ("Test Connection" button in Connection Settings)
I get the following error:
Connection to localhost:5432 refused.
Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
Connection refused: connect
I was following this tutorial that did not use DBeaver: https://medium.com/better-programming/connect-from-local-machine-to-postgresql-docker-container-f785f00461a7
If you got here from the official Postgres Docker page, don't forget to add the port-forwarding flag -p 5432:5432 to your initialization command like Rioh did above:
docker run --name RiohRoweDB -e POSTGRES_PASSWORD=Charlie -d -p 5432:5432 postgres
Also consider studying this how-to on Medium:
https://medium.com/#wkrzywiec/database-in-a-docker-container-how-to-start-and-whats-it-about-5e3ceea77e50
If you're using Docker Toolbox, programs on the host need to use the IP address from docker-machine ip, usually 192.168.99.100, to reach container processes; localhost won't work. – David Maze

Docker Rundeck + local Postgres

I'm trying to run a docker image of rundeck, using PostGres for the database.
The issue I'm having is mapping my local postgres installation to the docker rundeck image. The postgres port runs on 5432, and have confirmed using netstat that the port is open and listening. The port for rundeck needs to run on 4440.
I have tried the following command:
docker run -p 127.0.0.1:4440:4440 -e RUNDECK_DATABASE_URL=jdbc:postgresql://localhost/rundeck -e RUNDECK_DATABASE_DRIVER=org.postgresql.Driver -e RUNDECK_DATABASE_USERNAME=xxx -e RUNDECK_DATABASE_PASSWORD=xxx --name test-rundeck -t rundeck/rundeck:3.0.19
But it fails with an error: Connection to 127.0.0.1:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP
I'm guessing it's because the internal 5432 port isnt mapped to the docker container port 5432?
I tried mapping the ports with -p 127.0.0.1:5432:5432 but that fails with the error:
Error starting userland proxy: listen tcp 127.0.0.1:5432: bind: address already in use
At this point I might just resort to running both PostGres and Rundeck as docker images, but I would rather like to resolve this problem.
Any ideas on how to map a local PostGres to a docker ran Rundeck?
Found the answer.
Had to edit the pg_hba.conf file to allow the docker0 ip address through.
host all all 172.23.0.0/16 md5

Error when running psql command in /docker-entrypoint-initdb.d/db_init.sh (psql: could not connect to server: Connection refused)

I used to use a script (/docker-entrypoint-initdb.d/db_init.sh) to loop through database dumps in a folder copied into the postgres container and restoring them. It used to work nicely but recently it stopped working.
I get following error:
postgres_server_1 | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/db_init.sh
postgres_server_1 | --> db_init.sh: Found /dumps/dataset_1.dump as dataset_1
postgres_server_1 | psql: could not connect to server: Connection refused
postgres_server_1 | Is the server running on host "localhost" (127.0.0.1) and accepting
postgres_server_1 | TCP/IP connections on port 5432?
The db_init.sh script loops through a folder containing database dumps and checks if the database exists already. If not it restores the dump.
/docker-entrypoint-initdb.d/db_init.sh content:
shopt -s nullglob
for i in /dumps/*.dump;
do
db_name=${i##*/}
db_name=${db_name%.dump}
echo "--> db_init.sh: Found $i as $db_name"
if psql -U postgres -h localhost -lqt | cut -d \| -f 1 | grep -qw ${db_name}; then
echo "--> db_init.sh: Database ${db_name} already exists."
else
echo "--> db_init.sh: Setting up database: ${db_name}"
createdb -U postgres -h localhost-T template0 ${db_name}
psql -U postgres -h localhost ${db_name} < ${i}
fi
done
echo "--> db_init.sh: Setup complete."
I am using docker-compose to start the postgres container (and some others).
The docker-compose.yml content:
version: '3'
services:
postgres_server:
image: postgres
volumes:
- /etc/localtime:/etc/localtime:ro
- ./data/dumps:/dumps:ro
- ./scripts/db_init.sh:/docker-entrypoint-initdb.d/db_init.sh
environment:
- TZ=Europe/Berlin
restart: always
volumes:
postgres_data:
driver: local
Now what I don't understand is why there seems to be a connection error usually associated with trying to connect to a postgres database from a different machine or container. But the script itself is running in the postgres container and a volume connects the directory containing the dumps into the container.
Running the psql command from within the container using docker exec -it container_name bash works fine and the dumps are there. Why do the psql commands work when executing them manually from within the container but not when executed via /docker-entrypoint-initdb.d/db_init.sh?
It looks like this commit has broken your script.
Explanation:
PostgreSQL may accept connections not only via TCP/IP, but also via UNIX socket. The -h localhost argument tells psql to use TCP connections rather than UNIX socket.
If you look into the current docker-entrypoint.sh version, you will see, that during the execution of scripts in /docker-entrypoint-initdb.d PostgreSQL listens only on the UNIX socket, and the startup log says:
LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
This means that psql -h localhost will not connect to the database, as PostgreSQL does not listen on IP socket. You must use psql without -h localhost option to make it use UNIX socket instead of TCP connections.
But why running psql -h localhost manually works?
If you look into the docker-entrypoint.sh again, you will see that when all init scripts are executed, PostgreSQL is being stopped and then started again in normal (operational) mode, in which it listens both on UNIX and IP sockets:
LOG: listening on IPv4 address "0.0.0.0", port 5432
LOG: listening on IPv6 address "::", port 5432
LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
So, when the startup process is complete, you may connect to PostgreSQL using TCP connections, thus, entering into the container and running psql -h localhost succeeds.