ubuntu - postgres - docker tutorial español pdf
Permitir que el contenedor docker se conecte a una base de datos local/host de postgres (9)
Recientemente he estado jugando con Docker y QGIS y he instalado un contenedor siguiendo las instrucciones de este tutorial .
Todo funciona muy bien, aunque no puedo conectarme a una base de datos localgres de postgres que contiene todos mis datos SIG. Supongo que esto se debe a que mi base de datos postgres no está configurada para aceptar conexiones remotas y he estado editando los archivos conf de postgres para permitir conexiones remotas utilizando las instrucciones de este artículo .
Todavía recibo un mensaje de error cuando intento conectarme a mi base de datos que ejecuta QGIS en Docker: no se pudo conectar al servidor:
Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections to port 5433?
El servidor postgres se está ejecutando, y he editado mi archivo
pg_hba.conf
para permitir conexiones desde un rango de direcciones IP (172.17.0.0/32).
Anteriormente había consultado la dirección IP del contenedor docker usando
docker ps
y aunque la dirección IP cambia, hasta ahora siempre ha estado en el rango 172.17.0.x
¿Alguna idea de por qué no puedo conectarme a esta base de datos? ¡Probablemente algo muy simple, me imagino!
Estoy ejecutando Ubuntu 14.04; Postgres 9.3
En Ubuntu:
Primero debe verificar si el puerto de la base de datos de Docker está disponible en su sistema siguiendo el comando:
sudo iptables -L -n
Salida de muestra:
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
Aquí
3306
se utiliza como puerto de base de datos Docker en 172.17.0.2 IP, si este puerto no está disponible, ejecute el siguiente comando:
sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
Ahora, puede acceder fácilmente a la base de datos de Docker desde su sistema local siguiendo la configuración
host: 172.17.0.2
adapter: mysql
database: DATABASE_NAME
port: 3307
username: DATABASE_USER
password: DATABASE_PASSWORD
encoding: utf8
En CentOS:
Primero debe verificar si el puerto de la base de datos de Docker está disponible en su firewall siguiendo el comando:
sudo firewall-cmd --list-all
Salida de muestra:
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:
Aquí
3307
se utiliza como puerto de base de datos Docker en 172.17.0.2 IP, si este puerto no está disponible, ejecute el siguiente comando:
sudo firewall-cmd --zone=public --add-port=3307/tcp
En el servidor, puede agregar el puerto permanentemente
sudo firewall-cmd --permanent --add-port=3307/tcp
sudo firewall-cmd --reload
Ahora, puede acceder fácilmente a la base de datos de Docker desde su sistema local mediante la configuración anterior.
Solución simple
Simplemente agregue
--network=host
a
docker run
.
¡Eso es todo!
De esta forma, el contenedor usará la red del host, por lo que
localhost
y
127.0.0.1
apuntarán al host (de manera predeterminada, apuntan a un contenedor).
Ejemplo:
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
Solución simple para mac:
La versión más reciente de Docker (18.03) ofrece una solución integrada de reenvío de puertos.
Dentro de su contenedor docker, simplemente configure el host db en
host.docker.internal
.
Esto se enviará al host en el que se ejecuta el contenedor de Docker.
La documentación para esto está aquí: https://docs.docker.com/docker-for-mac/networking/#per-container-ip-addressing-is-not-possible
Solución Docker para Mac
17.06 en adelante
Gracias al comentario de @Birchlabs, ahora es mucho más fácil con este nombre DNS especial solo para Mac disponible :
docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.host.internal
Desde 17.12.0-cd-mac46, se debe usar
docker.for.mac.localhost
lugar de
docker.for.mac.localhost
.
Vea la
nota de lanzamiento
para más detalles.
Versión antigua
La respuesta de @ helmbert explica bien el problema. Pero Docker para Mac no expone la red de puente , así que tuve que hacer este truco para solucionar la limitación:
$ sudo ifconfig lo0 alias 10.200.10.1/24
Abra
/usr/local/var/postgres/pg_hba.conf
y agregue esta línea:
host all all 10.200.10.1/24 trust
Abra
/usr/local/var/postgres/postgresql.conf
y edite change
listen_addresses
:
listen_addresses = ''*''
Recargue el servicio e inicie su contenedor:
$ PGDATA=/usr/local/var/postgres pg_ctl reload
$ docker run -e DB_PORT=5432 -e DB_HOST=10.200.10.1 my_app
Lo que hace esta solución es básicamente lo mismo con la respuesta de @ helmbert, pero usa una dirección IP que está conectada a
lo0
lugar de la interfaz de red
docker0
.
TL; DR
-
Use
172.17.0.0/16
como rango de direcciones IP, no172.17.0.0/32
. -
No use
localhost
para conectarse a la base de datos PostgreSQL en su host, sino a la IP del host. Para mantener el contenedor portátil, inicie el contenedor con el--add-host=database:<host-ip>
y use ladatabase
como nombre de host para conectarse a PostgreSQL. -
Asegúrese de que PostreSQL esté configurado para escuchar conexiones en todas las direcciones IP, no solo en
localhost
. Busque la configuraciónlisten_addresses
en el archivo de configuración de PostgreSQL, que normalmente se encuentra en/etc/postgresql/9.3/main/postgresql.conf
(créditos a @DazmoNorton).
Versión larga
172.17.0.0/32
no es un
rango
de direcciones IP, sino una sola dirección (normalmente
172.17.0.0
).
Ningún contenedor Docker obtendrá esa dirección asignada, porque es la dirección de red de la interfaz del puente Docker (
docker0
).
Cuando Docker se inicie, creará una nueva interfaz de red de puente, que puede ver fácilmente al llamar a
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
Como puede ver, en mi caso, la interfaz
docker0
tiene la dirección IP
172.17.42.1
con una máscara de red de
/16
(o
255.255.0.0
).
Esto significa que la dirección de red es
172.17.0.0/16
.
La dirección IP se asigna aleatoriamente, pero sin ninguna configuración adicional, siempre estará en la red
172.17.0.0/16
.
Para cada contenedor Docker, se asignará una dirección aleatoria de ese rango.
Esto significa que si desea otorgar acceso desde todos los contenedores posibles a su base de datos, use
172.17.0.0/16
.
La otra solución es el volumen de servicio. Puede definir un volumen de servicio y montar el directorio de datos PostgreSQL del host en ese volumen. Echa un vistazo al archivo de composición dado para más detalles.
version: ''2'' services: db: image: postgres:9.6.1 volumes: - "/var/lib/postgresql/data:/var/lib/postgresql/data" ports: - "5432:5432"
Al hacer esto, otro servicio PostgreSQL se ejecutará en un contenedor, pero usa el mismo directorio de datos que el servicio host PostgreSQL está usando.
Para configurar algo simple que permita una conexión Postgresql desde el contenedor docker a mi host local, utilicé esto en postgresql.conf:
version: ''2''
services:
db:
image: postgres:9.6.1
volumes:
- "/var/lib/postgresql/data:/var/lib/postgresql/data"
ports:
- "5432:5432"
Y agregó este pg_hba.conf:
host all all 172.17.0.0/16 password
Luego reinicia. Mi cliente desde el contenedor docker (que estaba en 172.17.0.2) podría conectarse a Postgresql ejecutándose en mi host local usando el host: contraseña, base de datos, nombre de usuario y contraseña.
Una cosa más que necesitaba para mi configuración era agregar
172.17.0.1 localhost
a
/etc/hosts
para que Docker apunte a
172.17.0.1
como el nombre de host de la base de datos y no confíe en una IP externa cambiante para encontrar la base de datos.
¡Espero que esto ayude a alguien más con este problema!
para docker-compose puedes intentar simplemente agregar
network_mode: "host"
ejemplo:
version: ''2''
services:
feedx:
build: web
ports:
- "127.0.0.1:8000:8000"
network_mode: "host"