web-dev-qa-db-fra.com

Échec de la connexion à l'instance Docker Postgresql à partir de Python

J'utilise Docker pour "conteneuriser" un déploiement PostgreSQL. Je peux faire tourner le conteneur et me connecter à PostgreSQL via la ligne de commande, comme indiqué ci-dessous:

minime2@CEBERUS:~/Projects/skunkworks$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
dc176901052a        df:pg               "docker-entrypoint..."   About an hour ago   Up About an hour    5432/tcp            vigilant_agnesi

minime2@CEBERUS:~/Projects/skunkworks$ CONTAINER_ID=dc176901052a
minime2@CEBERUS:~/Projects/skunkworks$ IP=$(docker inspect -f '{{.NetworkSettings.Networks.bridge.IPAddress}}' $CONTAINER_ID)

minime2@CEBERUS:~/Projects/skunkworks$ echo $IP
172.17.0.2


minime2@CEBERUS:~/Projects/skunkworks$ docker exec -it vigilant_agnesi psql -U postgres -W cookiebox
Passwod for user postgres:
psql (9.6.5)
Type "help" for help

cookiebox#

Tentative de connexion avec Python:

Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> conn = psycopg2.connect("dbname='cookiebox' user='postgres' Host='172.17.0.2' password='nunyabiznes'")                                     Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/minime2/Projects/skunkworks/archivers/env/lib/python3.5/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: Connection refused
        Is the server running on Host "172.17.0.2" and accepting
        TCP/IP connections on port 5432?

>>> 

Quelqu'un peut-il expliquer pourquoi je ne peux pas me connecter à PostgreSQL avec Python - même si j'utilise les mêmes arguments/paramètres qui permettent une connexion réussie sur la ligne de commande (avec docker exec?).

[[Information additionnelle]]

Comme suggéré par @Itvhillo, j'ai essayé d'utiliser une application de bureau pour me connecter au service PG. J'exécute le service Docker à l'aide de la commande suivante:

docker run -i -p 5432:5432 --name $CONTAINER_NAME $DOCKER_IMAGE

J'utilise Db Visualizer pour me connecter à la base de données et j'ai défini le nom d'hôte sur 'localhost'. Je peux envoyer une requête ping avec le port avec succès, mais je reçois quand même un message d'erreur lorsque je tente de me connecter à la base de données (erreur liée aux autorisations possibles):

An error occurred while establishing the connection:

Long Message:
The connection attempt failed.

Details:
   Type: org.postgresql.util.PSQLException
   SQL State: 08001

Incidemment, il s'agit de la fin de la sortie pour l'instance de service PG:

PostgreSQL init process complete; ready for start up.

LOG:  could not bind IPv6 socket: Cannot assign requested address
HINT:  Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
LOG:  database system was shut down at 2018-01-30 16:21:59 UTC
LOG:  MultiXact member wraparound protections are now enabled
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started

[[Informations additionnelles2]]

Voici la fin de mon fichier Dockerfile:

# modified target locations (checked by login onto Docker container)
# show hba_file;
# show config_file;

#################################################################################
# From here: https://docs.docker.com/engine/examples/postgresql_service/
# Adjust PostgreSQL configuration so that remote connections to the
# database are possible.
RUN echo "Host all  all    0.0.0.0/0  md5" >> /var/lib/postgresql/data/pg_hba.conf

# And add ``listen_addresses`` to ``/var/lib/postgresql/data/postgresql.conf``
RUN echo "listen_addresses='*'" >> /var/lib/postgresql/data/postgresql.conf
#################################################################################


EXPOSE 5432

# Add VOLUMEs to allow backup of config, logs and databases
VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql", "/usr/lib/postgresql/"]
13

Si vous courez

$ docker run -i -p 5432:5432 --name $CONTAINER_NAME $DOCKER_IMAGE

Ensuite, vous devriez pouvoir vous connecter à localhost:5432 à partir de l'hôte. Le moyen le plus simple de vérifier si quelque chose écoute sur le port 5432 consiste à utiliser netcat. En cas de succès, vous devriez obtenir:

$ nc -zv localhost 5432 
Connection to localhost 5432 port [tcp/postgresql] succeeded!

Dans ce cas, vous devriez pouvoir vous connecter en utilisant:

>>> psycopg2.connect("dbname='cookiebox' user='postgres' Host='localhost' password='nunyabiznes'") 

Si, par contre, vous obtenez quelque chose comme:

$ nc -zv localhost 5432 
nc: connect to localhost port 5432 (tcp) failed: Connection refused

Ensuite, cela signifie que PostgreSQL n’écoute pas et qu’il ya donc quelque chose qui ne va pas dans votre fichier Docker, et vous aurez besoin de publier plus de détails sur votre fichier Docker pour le diagnostiquer.

7
Stefano Taschini

Il semble que PostgreSQL ne puisse pas lier socket pour écouter les connexions TCP pour une raison quelconque. Il écoute toujours le socket UNIX par défaut à l'intérieur du conteneur, vous pouvez donc vous y connecter via docker exec -it $CONTAINER_NAME psql.

3
ei-grad

Dans le fichier postgresql.conf, changez Listen_addresses = 'localhost' en listen_addresses = '*' Ensuite, essayez de vous connecter via psql

psql -h docker-ip -u nom d'utilisateur -w

0
Lennin

Essayez d'isoler le problème: exécutez une instance postgres propre sans aucune extension sur le port par défaut:

docker run  -d --name tst-postgres-01 -p 5432:5432 -e POSTGRES_PASSWORD=mysecretpassword postgres:9.6

Et essayez de vous y connecter. Si vous le pouvez, vous devez alors examiner votre fichier Dockerfile en conséquence: supprimez tout ce qui s'y trouve, puis ajoutez de nouveaux éléments un par un. Sinon, s'il ne se connecte pas, essayez de l'exécuter sur un autre port:

docker run  -d --name tst-postgres-01 -p 45432:5432 -e POSTGRES_PASSWORD=mysecretpassword postgres:9.6

Et essayez de vous connecter. Si cela fonctionne cette fois, alors le problème de votre configuration réseau sur la machine hôte, le port 5432 est bloqué ou utilisé par une autre application.

0
Moisei