我曾考虑使用像 Stitch Data 或 Skyvia 这样的 ETL 服务来整合不同的数据源(包括我的 Discourse 数据库),但 Skyvia 的一位人员告诉我这是不可能的:
Skyvia 可以通过 SSH 连接 PostgreSQL,但如果 PostgreSQL 位于 Docker 容器内,而 SSH 服务器不在容器内而是在其前方,则无法连接。
这是他们连接 PostgreSQL 的 要求。
是否有明显的解决方案?
我曾考虑使用像 Stitch Data 或 Skyvia 这样的 ETL 服务来整合不同的数据源(包括我的 Discourse 数据库),但 Skyvia 的一位人员告诉我这是不可能的:
Skyvia 可以通过 SSH 连接 PostgreSQL,但如果 PostgreSQL 位于 Docker 容器内,而 SSH 服务器不在容器内而是在其前方,则无法连接。
这是他们连接 PostgreSQL 的 要求。
是否有明显的解决方案?
您可以在 Discourse 容器(使用非标准端口)中启用 SSH,然后允许用户连接。我认为 Discourse_docker 的 samples 目录中可能有相关示例。
谢谢,Jay。我最终使用了 docker-ssh 配合公钥认证。![]()
我似乎漏掉了一个关键概念,因为我能够通过自定义端口使用 SSH 连接,然后执行 su postgres -c 'psql discourse' 而没有任何问题。这种两步法一切正常,但我认为想要直接通过 pgAdmin(例如)连接,需要一些略微不同的配置。
这是我用来暴露自定义端口的命令:
docker run -d -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.ssh/authorized_keys:/authorized_keys \
--name my-sshd \
-e FILTERS={\"name\":[\"^/app$\"]} -e AUTH_MECHANISM=publicKey \
-e AUTHORIZED_KEYS=/authorized_keys \
jeroenpeeters/docker-ssh
这使得我之后可以直接执行以下操作(无需通过 launcher enter app 运行 Docker 容器):
ssh whatever@host -p 2222
su postgres -c 'psql discourse'
我尝试了多种方法,但均未成功。我觉得应该有一种方法可以执行 ssh whatever@host -p XXXX 并直接连接到数据库(这很可能就是 pgAdmin 所期望的)。
您无法连接,还是遇到了权限问题?
我可以通过命令行使用 ssh 连接,然后使用 psql 连接。但我无法通过 pgAdmin 连接。
您需要直接暴露 PostgreSQL 端口,才能通过 pgAdmin 进行连接。
在 app.yml 文件顶部附近,您会看到 80 和 443 端口已开放。您可以添加一行来开放 PostgreSQL 的端口 5432。
不过,这极大概率是一个非常糟糕的做法。数据库从仅接受本地连接变为向整个互联网暴露。
如果您只是需要偶尔生成报告,从数据浏览器(Data Explorer)下载一些 CSV 文件并在您喜欢的工具中加载可能就足够了。您也可以下载 Discourse 备份(不包含上传文件),这些备份采用标准的 PostgreSQL 转储格式。有了这些文件,您就可以将其恢复到本地的 PostgreSQL 实例中进行分析。
如果你在 app.yml 中添加 5432,该端口将直接暴露,无需通过 SSH 隧道。
我无法就 pgAdmin 的 SSH 隧道提供建议,因为我从未使用过它。我假设它期望端口监听本地连接,因此不需要暴露给互联网。
尝试以下配置:
expose:
- "80:80"
- "443:443"
- "5432"
但是因为没有 PostgreSQL 密码,因为它需要超级用户权限:pg_hba.conf 文件将“local”连接权限设置为“peer”,所以它依赖于 UNIX 用户,这需要 SSH 登录,对吗?
这不起作用:psql -h XX.XX.XX.XX -p 5432 -U postgres -d discourse
您可以以超级用户身份连接到 psql
./launcher enter app
su postgres
psql
然后为您的报表创建具有必要权限的用户。
好的,从应用 Docker 容器内部连接没有问题。我的问题在于无法直接从本地机器(以便使用 pgAdmin)或从像 Stitch 这样的云端数据处理器直接连接到 PostgreSQL 数据库。这两者都期望提供主机 IP 地址和 SSH 凭据,但我一直无法让它们正常工作(我遇到了上面显示的错误)。
我目前唯一能做到的,是通过 docker-ssh 从本地计算机(无需执行 launcher enter app)使用公钥直接访问应用 Docker 容器。不过,我仍然需要执行 su postgres 'psql discourse' 才能访问数据库。我推测这就是 pgAdmin 和 Stitch 无法工作的原因——它们期望的是直接连接。
您是否尝试过创建一个带密码的新 PostgreSQL 实例,并将其密码提供给您的服务?
是的,他们有一套相当冗长的流程。
不过,我在本地计算机上直接使用 pgAdmin 时也遇到了同样的问题。
我认为 如何从独立容器迁移到分离的 Web 和数据容器 这篇帖子中可能包含设置密码的说明。
此外,我认为你可以将 PostgreSQL 端口仅绑定到 127.0.0.1。
expose:
- "80:80"
- "443:443"
- "127.0.0.1:5432:5432"
我决定退一步,看看是否能在不暴露任何端口的情况下连接到数据库。![]()
如果进入容器,我会看到以下内容:
# netstat -lp | grep postgres
tcp 0 0 0.0.0.0:postgresql 0.0.0.0:* LISTEN -
tcp6 0 0 [::]:postgresql [::]:* LISTEN -
unix 2 [ ACC ] STREAM LISTENING 263612292 - /var/run/postgresql/.s.PGSQL.5432
如果退出容器并处于远程服务器上(尚未在本地计算机上),我是否应该能够使用以下命令进行连接?
/var/discourse# psql -h localhost -d discourse -U postgres
问题是我遇到了密码提示。由于 postgres 用户没有设置密码,我尝试创建另一个用户并为其分配密码:
CREATE USER whatever_user WITH ENCRYPTED PASSWORD '<whatever password>';
GRANT CONNECT ON DATABASE discourse TO whatever_user;
GRANT USAGE ON SCHEMA public TO whatever_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whatever_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO whatever_user;
我在 pg_hba.conf 中为该用户添加了一行 md5 配置,并使用 service postgresql restart 重启了 PostgreSQL:
# Database administrative login by Unix domain socket
local all postgres peer
local all whatever_user md5
然而,当我尝试从远程服务器连接时,却收到了身份验证失败的错误:
# psql -h localhost -d discourse -U whatever_user
Password for user whatever_user:
psql: FATAL: password authentication failed for user "whatever_user"
FATAL: password authentication failed for user "whatever_user"
我遗漏了什么?我至少希望能够在同一台服务器上连接到数据库。第二步是通过 SSH 隧道实现相同功能,但我想需要先解决第一步。任何帮助都将不胜感激。
好的,我终于搞定了 ![]()
我把这个:
改成了 - "127.0.0.1:5433:5432",因为我收到了端口已被占用的错误提示。
我重新构建了容器,并确认端口确实已开放:
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
whatever_id local_discourse/app "/sbin/boot" 20 minutes ago Up 20 minutes 127.0.0.1:5433->5432/tcp app
现在我能够创建 SSH 隧道,并使用带密码的用户从远程服务器连接:
# 创建隧道(你也可以使用 ssh -f 在后台运行)
ssh -v -N -L 5433:localhost:5433 SERVER_IP_ADDRESS
# 在另一个标签页中连接并输入密码
psql -h localhost -d discourse -U whatever_user -p 5433
如果任何人尝试这样做时遇到任何问题,请告诉我。