Разрешить контейнеру docker подключаться к локальной / хост-базе данных postgres
недавно я играл с Docker и QGIS и установил контейнер, следуя инструкциям в в этом уроке.
все работает отлично, хотя я не могу подключиться к базе данных localhost postgres, которая содержит все мои данные ГИС. Я полагаю, это потому, что моя база данных postgres не настроена для приема удаленных подключений и редактировала файлы postgres conf, чтобы разрешить удаленные подключения с помощью инструкций в в этой статье.
Я все еще получаю сообщение об ошибке при попытке подключиться к моей базе данных под управлением QGIS в Docker: не удалось подключиться к серверу:Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections to port 5433?
Сервер postgres запущен, и я отредактировал свой файл pg_hba.conf Разрешить подключения из диапазона IP-адресов (172.17.0.0/32). Ранее я запросил IP-адрес контейнера docker с помощью docker ps
и хотя IP-адрес изменяется, он до сих пор всегда был в диапазоне 172.17.0.x
любые идеи, почему я не могу подключиться к этой базе? Наверное, что-то очень простое!
Я запускаю Ubuntu 14.04; Postgres 9.3
6 ответов
TL; DR
- использовать
172.17.0.0/16
как диапазон IP-адресов, а не172.17.0.0/32
. - не используйте
localhost
для подключения к базе данных PostgreSQL на вашем Хосте, но вместо этого IP хоста. Чтобы сохранить контейнер портативным, запустите контейнер с помощью--add-host=database:<host-ip>
флаг и использоватьdatabase
как имя хоста для подключения к PostgreSQL. - убедитесь, что PostreSQL настроен для прослушивания соединений на всех IP-адресах, а не только на
localhost
. Ищите настройкиlisten_addresses
in Файл конфигурации PostgreSQL, как правило, находится в/etc/postgresql/9.3/main/postgresql.conf
(кредиты @DazmoNorton).
текст
172.17.0.0/32
- это не ряд IP-адресов, но один адрес (namly 172.17.0.0
). Ни один контейнер Docker никогда не получит этот адрес, потому что это сетевой адрес моста Docker (docker0
интерфейс).
когда Docker запускается, он создаст новый сетевой интерфейс моста, который вы можете легко увидеть, когда зову 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
как вы можете видеть, в моем случае docker0
интерфейс имеет IP-адрес 172.17.42.1
С маской /16
(или 255.255.0.0
). Это означает, что сетевой адрес 172.17.0.0/16
.
IP-адрес назначается случайным образом, но без какой-либо дополнительной конфигурации он всегда будет в 172.17.0.0/16
сеть. Для каждого контейнера Docker будет назначен случайный адрес из этого диапазона.
это означает, если вы хотите предоставить доступ из всех возможных контейнеров к вашей базе данных, используйте 172.17.0.0/16
.
Docker для Mac решение
17.06 и далее
благодаря комментарию @Birchlabs, теперь это намного проще с этим специальный Mac-доступно только DNS-имя:
docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.host.internal
от 17.12.0-cd-mac46,docker.for.mac.host.internal
вместо docker.for.mac.localhost
. См.версии для сведения.
старая версия
ответ@helmbert хорошо объясняет проблему. Но Докер для Mac не подвергайте сеть мостов, поэтому мне пришлось сделать этот трюк, чтобы обойти ограничение:
$ sudo ifconfig lo0 alias 10.200.10.1/24
открыть /usr/local/var/postgres/pg_hba.conf
и добавить эту строку:
host all all 10.200.10.1/24 trust
открыть /usr/local/var/postgres/postgresql.conf
редактировать и изменять listen_addresses
:
listen_addresses = '*'
перезагрузите сервис и запустите контейнер:
$ PGDATA=/usr/local/var/postgres pg_ctl reload
$ docker run -e DB_PORT=5432 -e DB_HOST=10.200.10.1 my_app
то, что этот обходной путь делает в основном то же самое с ответом @helmbert, но использует IP-адрес, который прикреплен к lo0
вместо docker0
сетевой интерфейс.
простое решение для mac:
новейшая версия docker (18.03) предлагает встроенное решение для переадресации портов. Внутри вашего контейнера docker просто установите хост db в host.docker.internal
. Это будет перенаправлено на хост, на котором работает контейнер docker.
документация для этого здесь: https://docs.docker.com/docker-for-mac/networking/#per-container-ip-addressing-is-not-possible
еще одна вещь, необходимая для моей установки, - это добавить
172.17.0.1 localhost
to /etc/hosts
чтобы Докер указал на 172.17.0.1
как имя хоста БД, а не полагаться на изменение внешнего ip-адреса для поиска БД. Надеюсь, это поможет кому-то еще с этой проблемой!
В Ubuntu:
сначала вы должны проверить, что порт базы данных Docker доступен в вашей системе, выполнив команду -
sudo iptables -L -n
выход образца:
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
здесь 3306
используется в качестве порта базы данных Docker на 172.17.0.2 IP, если этот порт недоступен выполните следующую команду -
sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
теперь вы можете легко получить доступ к базе данных Docker из локальной системы, следуя конфигурация
host: 172.17.0.2
adapter: mysql
database: DATABASE_NAME
port: 3307
username: DATABASE_USER
password: DATABASE_PASSWORD
encoding: utf8
В CentOS:
сначала вы должны проверить, что порт базы данных Docker доступен в вашем брандмауэре, выполнив команду -
sudo firewall-cmd --list-all
выход образца:
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:
здесь 3307
используется в качестве порта базы данных Docker на 172.17.0.2 IP, если этот порт недоступен выполните следующую команду -
sudo firewall-cmd --zone=public --add-port=3307/tcp
sudo firewall-cmd --reload
теперь вы можете легко получить доступ к базе данных Docker из вашей локальной системы выше конфигурация.
другое решение-том службы, вы можете определить том службы и подключить каталог данных PostgreSQL хоста в этом томе. Проверьте данный файл compose для деталей.
version: '2'
services:
db:
image: postgres:9.6.1
volumes:
- "/var/lib/postgresql/data:/var/lib/postgresql/data"
ports:
- "5432:5432"
при этом другая служба PostgreSQL будет работать в контейнере, но использует тот же каталог данных, который использует Служба PostgreSQL.