web-dev-qa-db-fra.com

Autoriser le conteneur Docker à se connecter à une base de données postgres locale / hôte

J'ai récemment joué avec Docker et QGIS et ai installé un conteneur en suivant les instructions de ce tutoriel .

Tout fonctionne très bien, même si je ne parviens pas à me connecter à une base de données posthres localhost contenant toutes mes données SIG. Je suppose que c'est parce que ma base de données postgres n'est pas configurée pour accepter les connexions distantes et a modifié les fichiers postgres conf pour autoriser les connexions distantes à l'aide des instructions de cet article .

Je reçois toujours un message d'erreur lorsque j'essaie de me connecter à ma base de données exécutant QGIS dans Docker: impossible de se connecter au serveur: Connection refused Is the server running on Host "localhost" (::1) and accepting TCP/IP connections to port 5433? Le serveur postgres est en cours d'exécution et j'ai modifié mon pg_hba.conf fichier permettant les connexions à partir d'une plage d'adresses IP (172.17.0.0/32). J'avais précédemment demandé l'adresse IP du conteneur de menu fixe en utilisant docker ps et bien que l'adresse IP ait changé, elle a toujours été dans la plage 172.17.0.x

Des idées pour lesquelles je ne peux pas me connecter à cette base de données? Probablement quelque chose de très simple j'imagine!

J'utilise Ubuntu 14.04; Postgres 9.3

91
marty_c

TL; DR

  1. Utilisez 172.17.0.0/16 comme plage d'adresses IP et non pas 172.17.0.0/32.
  2. N'utilisez pas localhost pour vous connecter à la base de données PostgreSQL sur votre hôte, mais à l'adresse IP de l'hôte. Pour que le conteneur reste portable, démarrez-le avec l'indicateur --add-Host=database:<Host-ip> et utilisez database comme nom d'hôte pour vous connecter à PostgreSQL.
  3. Assurez-vous que PostreSQL est configuré pour écouter les connexions sur toutes les adresses IP, pas seulement sur localhost. Recherchez le paramètre listen_addresses dans le fichier de configuration de PostgreSQL, qui se trouve généralement dans /etc/postgresql/9.3/main/postgresql.conf (crédité à @DazmoNorton).

Version longue

172.17.0.0/32 n'est pas une plage d'adresses IP, mais une adresse unique (nommément 172.17.0.0). Aucun conteneur Docker ne se verra jamais attribuer cette adresse, car il s'agit de l'adresse réseau de l'interface du pont Docker (docker0).

Lorsque Docker démarre, il crée une nouvelle interface réseau de pont, que vous pouvez facilement voir en appelant ip a:

$ ip a
...
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever

Comme vous pouvez le voir, dans mon cas, l'interface docker0 a l'adresse IP 172.17.42.1 avec un masque de réseau de /16 (ou 255.255.0.0). Cela signifie que l'adresse réseau est 172.17.0.0/16.

L'adresse IP est attribuée de manière aléatoire, mais sans configuration supplémentaire, elle sera toujours dans le réseau 172.17.0.0/16. Pour chaque conteneur Docker, une adresse aléatoire de cette plage sera attribuée.

Cela signifie que si vous souhaitez autoriser l'accès à votre base de données depuis tous les conteneurs possibles, utilisez 172.17.0.0/16.

114
helmbert

Solution Docker pour Mac

17.06 à partir de

Grâce au commentaire de @Birchlabs, c'est maintenant beaucoup plus facile avec ceci nom DNS spécial disponible uniquement sur Mac :

docker run -e DB_PORT=5432 -e DB_Host=docker.for.mac.Host.internal

A partir de 17.12.0-cd-mac46, docker.for.mac.Host.internal devrait être utilisé à la place de docker.for.mac.localhost. Voir note de version pour plus de détails.

Ancienne version

La réponse de @ helmbert explique bien le problème. Mais Docker pour Mac n’expose pas le pont , j’ai donc dû faire cette astuce pour contourner la limitation:

$ Sudo ifconfig lo0 alias 10.200.10.1/24

Ouvrez /usr/local/var/postgres/pg_hba.conf et ajoutez cette ligne:

Host    all             all             10.200.10.1/24            trust

Ouvrez /usr/local/var/postgres/postgresql.conf et modifiez la modification listen_addresses:

listen_addresses = '*'

Rechargez le service et lancez votre conteneur:

$ PGDATA=/usr/local/var/postgres pg_ctl reload
$ docker run -e DB_PORT=5432 -e DB_Host=10.200.10.1 my_app 

Ce que cette solution de contournement fait est fondamentalement identique à la réponse de @ helmbert, mais utilise une adresse IP associée à lo0 au lieu de docker0 interface réseau.

48
baxang

Solution simple pour mac:

La dernière version de docker (18.03) offre une solution de transfert de port intégrée. Dans votre conteneur de menu fixe, placez simplement l'hôte de base de données sur Host.docker.internal. Cela sera transmis à l'hôte sur lequel le conteneur docker est en cours d'exécution.

La documentation à cet effet est disponible ici: https://docs.docker.com/docker-for-mac/networking/#per-container-ip-addressing-is-not-possible

23
Chris

Solution simple

Ajoutez simplement --network=Host à docker run. C'est tout!

De cette façon, le conteneur utilisera le réseau de l'hôte. Ainsi, localhost et 127.0.0.1 pointeront vers l'hôte (ils désignent par défaut un conteneur). Exemple:

docker run -d --network=Host \
  -e "DB_DBNAME=your_db" \
  -e "DB_PORT=5432" \
  -e "DB_USER=your_db_user" \
  -e "DB_PASS=your_db_password" \
  -e "DB_Host=127.0.0.1" \
  --name foobar foo/bar
2
Max Malysh

pour docker-compos, vous pouvez essayer d'ajouter simplement

network_mode: "Host"

exemple :

version: '2'
services:
  feedx:
    build: web
    ports:
    - "127.0.0.1:8000:8000"
    network_mode: "Host"

https://docs.docker.com/compose/compose-file/#network_mode

1
Sarath Ak

Dans Ubuntu:

Vous devez d’abord vérifier que le port de la base de données Docker est disponible sur votre système en suivant la commande -

Sudo iptables -L -n

Exemple de sortie:

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3306
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:22

Ici 3306 est utilisé comme port de base de données Docker sur 172.17.0.2 IP, si ce port n'est pas disponible Exécutez la commande suivante -

Sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

Maintenant, vous pouvez facilement accéder à la base de données Docker à partir de votre système local en suivant la configuration.

  Host: 172.17.0.2 
  adapter: mysql
  database: DATABASE_NAME
  port: 3307
  username: DATABASE_USER
  password: DATABASE_PASSWORD
  encoding: utf8

En CentOS:

Vous devez d’abord vérifier que le port de la base de données Docker est disponible dans votre pare-feu en suivant la commande -

Sudo firewall-cmd --list-all

Exemple de sortie:

  target: default
  icmp-block-inversion: no
  interfaces: eno79841677
  sources: 
  services: dhcpv6-client ssh
  **ports: 3307/tcp**
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules:

Ici 3307 est utilisé comme port de base de données Docker sur 172.17.0.2 IP, si ce port n'est pas disponible Exécutez la commande suivante -

Sudo firewall-cmd --zone=public --add-port=3307/tcp

En serveur, vous pouvez ajouter le port de manière permanente

Sudo firewall-cmd --permanent --add-port=3307/tcp
Sudo firewall-cmd --reload

Vous pouvez maintenant accéder facilement à la base de données Docker à partir de votre système local grâce à la configuration ci-dessus.

1
Sanaulla

Une autre chose nécessaire pour ma configuration était d’ajouter

172.17.0.1  localhost

à /etc/hosts

de sorte que Docker pointe le nom 172.17.0.1 en tant que nom d’hôte de la base de données et ne s’appuie pas sur une adresse IP externe modifiée pour rechercher la base de données. J'espère que cela aide quelqu'un d'autre avec ce problème!

0
Mikko Pöri