Разрешить Docker контейнеру подключаться к локальной / хостовой базе данных postgres

53

Недавно я играл с 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 ps, и хотя IP-адрес изменяется, он до сих пор всегда находился в диапазоне 172.17.0.x

Любые идеи, почему я не могу подключиться к этой базе данных? Наверное, что-то очень простое, я думаю!

Я запускаю Ubuntu 14.04; Postgres 9.3

Теги:
docker
qgis
postgresql-9.3

4 ответа

64
Лучший ответ

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 в файле конфигурации PostgreSQL, обычно находящемся в /etc/postgresql/9.3/main/postgresql.conf (кредиты @DazmoNorton).

Длинная версия

172.17.0.0/32 не является диапазоном IP-адресов, а единственным адресом (namly 172.17.0.0). Контейнер Docker никогда не получит этот адрес, потому что это сетевой адрес интерфейса Docker bridge (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.

  • 1
    эй спасибо за ваши комментарии Я изменил свой pg_hba.conf на предложенный вами адрес, но все равно получаю то же сообщение об ошибке подключения после остановки и перезапуска службы postgres. Я добавил строку под своими соединениями ipv4 - где-то еще я должен добавить адрес, который вы предлагаете? В качестве альтернативы в моем приложении QGIS, работающем в Docker, мне нужно изменить информацию о соединении postgres? Например, если я подключаюсь из контейнера докера, хост все еще «localhost»?
  • 0
    Ах, это важный момент. Нет, localhost не является хост-системой внутри вашего контейнера Docker. Попробуйте подключиться к общедоступному IP-адресу хост-системы. Чтобы сохранить контейнер переносимым, вы также можете запустить контейнер с параметром --add-host=database:<host-ip> и просто использовать database качестве имени хоста для подключения к вашему хосту PostgreSQL из контейнера Docker.
Показать ещё 5 комментариев
19

Решение Docker для Mac

17.06 вперед

Благодаря комментарию @Birchlabs, теперь с этим доступно только имя для Mac-только:

docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.localhost 

Старая версия

@helmbert ответ хорошо объясняет проблему. Но Docker for 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.

  • 3
    Это все еще актуально на 4 апреля 2017 года?
  • 0
    Да, работал угощение для меня! Спасибо @baxang!
Показать ещё 5 комментариев
1

Еще одна вещь, необходимая для моей установки, заключалась в том, чтобы добавить

172.17.0.1  localhost

to /etc/hosts

чтобы Docker указывал на 172.17.0.1 как имя узла БД и не полагался на изменение внешнего ip для поиска БД. Надеюсь, это поможет кому-то еще с этой проблемой!

  • 7
    Это плохое решение. Localhost обычно должен указывать на 127.0.0.1. Его изменение может иметь нежелательные последствия, даже если в данном конкретном случае это работает.
  • 0
    Лучший способ - настроить хост database с параметром --add-host=database:172.17.0.1 при запуске контейнера. Затем укажите ваше приложение на этот хост. Это позволяет избежать жесткого кодирования IP-адреса внутри контейнера.
Показать ещё 1 комментарий
0

Другим решением является уровень обслуживания. Вы можете определить том службы и установить каталог данных PostgreSQL Host в том томе. Подробнее см. Данный файл компоновки.

version: '2'
services:
  db:   
    image: postgres:9.6.1
    volumes:
      - "/var/lib/postgresql/data:/var/lib/postgresql/data" 
    ports:
      - "5432:5432"

Таким образом, другая служба PostgreSQL будет работать под контейнером, но использует тот же каталог данных, который использует служба PostgreSQL.

  • 1
    Это, вероятно, вызовет конфликты записи с работающим хостом PostgreSQL.
  • 0
    Я думаю, что остановка службы хоста решит проблему в этом случае.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню