我最近一直在使用Docker和QGIS,并按照本教程中的说明安装了一个容器。

一切都很好,尽管我无法连接到包含我所有GIS数据的本地主机postgres数据库。我想这是因为我的postgres数据库没有配置为接受远程连接,并且一直在编辑postgres conf文件以允许使用本文中的说明进行远程连接。

I'm still getting an error message when I try and connect to my database running QGIS in Docker: could not connect to server: Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections to port 5433? The postgres server is running, and I've edited my pg_hba.conf file to allow connections from a range of IP addresses (172.17.0.0/32). I had previously queried the IP address of the docker container using docker ps and although the IP address changes, it has so far always been in the range 172.17.0.x

知道为什么我无法连接到这个数据库吗?我想可能是非常简单的事情!

我运行的是Ubuntu 14.04;Postgres 9.3


当前回答

让我解释一下我做了什么。

Postgresql

首先,我做了必要的配置,以确保我的Postgres数据库接受来自外部的连接。

打开pg_hba.conf,在最后添加如下一行:

host    all             all             0.0.0.0/0               md5

打开postgresql.conf,查找listen_addresses并像这样修改:

listen_addresses = '*'

确保上面的行没有使用#注释

->重启数据库

OBS:这不是生产环境的推荐配置

接下来,我寻找我的主机的ip。我使用的是localhosts ip 127.0.0.1,但是容器看不到它,所以在运行容器时出现了有问题的Connection Refused消息。在网上搜索了很长一段时间后,我读到容器看到了来自本地网络的内部ip(你的路由器将它属性为连接到它的每个设备,我不是在谈论让你访问互联网的ip)。也就是说,我打开了一个终端,做了以下事情:

查找本地网络ip

打开终端或CMD

(MacOS / Linux)

$ ifconfig

(窗口)

$ ipconfig

这个命令将显示您的网络配置信息。 看起来是这样的:

en4: 
    ether d0:37:45:da:1b:6e 
    inet6 fe80::188d:ddbe:9796:8411%en4 prefixlen 64 secured scopeid 0x7 
    inet 192.168.0.103 netmask 0xffffff00 broadcast 192.168.0.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (100baseTX <full-duplex>)
    status: active

寻找一个活跃的。

在我的例子中,我的本地网络ip是192.168.0.103

完成这些操作后,我运行容器。

码头工人

使用——add-host参数运行容器,如下所示:

$ docker run --add-host=aNameForYourDataBaseHost:yourLocalNetWorkIp --name containerName -di -p HostsportToBind:containerPort imageNameOrId

就我而言,我做到了:

$ docker run --add-host=db:192.168.0.103 --name myCon -di -p 8000:8000 myImage

我使用的是Django,所以默认端口是8000。

Django应用程序

访问数据库的配置如下:

在settings.py

DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': ‘myDataBaseName',
            'USER': ‘username',
            'PASSWORD': '123456',
            'HOST': '192.168.0.103',
            'PORT': 5432,
    }
}

参考文献

关于-p标志: 使用网口映射进行连接

关于docker run: Docker运行文档

有趣的文章: Docker提示#35:连接到运行在Docker主机上的数据库

其他回答

以防万一,上述解决方案并不适用于任何人。使用以下语句从docker连接到主机postgres(在mac上):

psql --host docker.for.mac.host.internal -U postgres

对于docker-compose,您可以尝试只添加

network_mode: "host"

例子:

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

在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”作为172.17.0.2 IP地址的“Docker数据库端口”,如果没有此端口执行以下命令-

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

In 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”作为172.17.0.2 IP地址的“Docker数据库端口”,如果没有此端口执行以下命令-

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

在服务器端,可以永久添加端口

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

现在,您可以通过上述配置轻松地从本地系统访问Docker数据库。

简单的解决方案

只需在docker run中添加——network=host。这是所有!

这样容器将使用主机的网络,因此localhost和127.0.0.1将指向主机(默认情况下它们指向容器)。例子:

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

您可以添加多个监听地址,以提高安全性。

listen_addresses = 'localhost,172.17.0.1'

添加listen_addresses = '*'不是一个好的选择,这是非常危险的,并且会将你的postgresql数据库暴露在蛮荒的西部。