【问题标题】:Connect to dockerized postgres from Windows Docker host从 Windows Docker 主机连接到 dockerized postgres
【发布时间】:2021-08-26 21:02:24
【问题描述】:

我的设置是安装了 postgres(不是数据库,只有命令行工具)的 Windows 10 Pro 机器上的 Docker for Windows(版本 18.09.2)。

我使用 docker hub 运行官方 postgres 映像

docker run -it -v D:/postgres:/home/dump --name some_postgres -e POSTGRES_PASSWORD=root -d postgres

之后我可以通过连接

docker exec -it <docker-id> bash

然后运行

psql -U postgres

一切正常。现在我想从我的主机连接。我打电话

psql -h <local-ip> -U postgres

得到了

psql: could not connect to server: Connection refused (0x0000274D/10061)
        Is the server running on host "192.168.116.74" and accepting
        TCP/IP connections on port 5432?

我很确定,可以访问数据库。因为如果我更改我收到的 IP

psql: could not connect to server: Connection timed out (0x0000274C/10060)
        Is the server running on host "192.168.116.11" and accepting
        TCP/IP connections on port 5432?

有没有人知道如何解决这个问题?还是我做错了什么?

【问题讨论】:

  • 事实证明,这个问题应该是:Connect to dockerized postgres from Windows Docker host when the standard port 5432 is already used by a Windows PostgreSQL installation? 这至少可能来自第一个答案下的 cmets,这表明肯定存在冲突。 OP 的评论“避免与可能在本地运行的数据库发生任何端口冲突”以及其他 cmets 中的误解使这很可能发生。改变这个问题是不公平的,因为当没有这样的占用端口 5432 时,第一个答案确实有效。

标签: windows postgresql docker


【解决方案1】:

要从您的主机连接到容器,您必须将端口发布到您的主机。这是使用端口发布和-p 选项完成的:

docker run -it -v D:/postgres:/home/dump --name some_postgres -p 5432:5432 -e POSTGRES_PASSWORD=root -d postgres

注意-p 选项。现在,当您尝试连接到本地主机上的端口 5432 时,流量将被重定向到容器的端口 5432

【讨论】:

  • 这没关系。如果你运行“docker ps”,你会看到容器已经发布了 5432 端口。你试过你的“解决方案”了吗?
  • 请复制并粘贴您的 docker ps 为 PORTS 列显示的内容。
  • 是的,我实际上使用 Docker For Windows 专门为您测试了它。使用我的解决方案,我可以从在我的主机上运行的客户端连接到 Postgres 实例。您的 PORTS 列可能显示 5432/tcp 但这并不意味着您可以从该端口上的主机访问容器 - 这意味着该容器在该端口上暴露了一些东西。对于“解决方案”,请检查我的答案。应用后,您将在 PORTS 列中获得0.0.0.0:5432-&gt;5432/tcp。顺便说一句,您是否尝试过我的“解决方案”?
  • 您的解决方案我之前尝试过,甚至在我在这里发布帖子之前。我已经将端口更改为5433:5432,以避免与可能在本地运行的数据库发生任何端口冲突。但还是一样。 40277b8c7256 postgres "docker-entrypoint.s…" 2 hours ago Up 2 hours 5432/tcp, 0.0.0.0:5432-&gt;5433/tcp p1psql -U postgres -h &lt;local-ip&gt; 导致 D:\&gt;psql -h 192.168.116.74 -U postgres -p 5433 psql: could not connect to server: Connection refused (0x0000274D/10061) Is the server running on host "192.168.116.74" and accepting TCP/IP connections on port 5433?
  • Up 2 hours 5432/tcp, 0.0.0.0:5432-&gt;5433/tcp - db 在端口 5432 上从容器中暴露出来,但我不知道为什么您将 localhost 的端口 5432 映射到容器中的 5433 - 可能没有任何内容暴露在端口5433 上的容器。使用我在答案中发布的命令并尝试运行psql -h localhost -U postgres -p 5432
【解决方案2】:

我花了很长时间才弄清楚如何从 Windows 上的普通 psql 提示符输入容器的数据库。这是由于额外的本地 Windows 安装造成的。


5432 创建一个没有端口冲突的 Docker 容器 (Linux)

端口参数的结构(docker rundocker-compose)是:

&lt;docker_host_port_on_linux&gt;:&lt;docker_container_port_on_linux&gt;

Connecting to Postgresql in a docker container from outside&lt;host_port&gt; 是您可以在 Windows 上找到的用于连接到容器端口的端口。这里似乎需要的核心技巧是避免another answer of the same thread 中的端口冲突。

如果您使用5432:5432,这可能与使用端口5432 作为标准的Windows 上本地安装的postgres 冲突。您可以通过打开 psql,使用菜单登录(在标准测试阶段,您可能只需要在任何菜单点按 Enter 键),然后使用 \l 打印所有可用的数据库来找出这种冲突。如果这些是您本地 Windows 安装的数据库,那么您知道在使用 docker 时必须使用另一个端口。

如果端口之间存在冲突,请为 Docker 主机使用新端口,或者带参数

-p 5433:5432

或者使用docker-compose时,文件需要有:

ports:
    - "5433:5432"

是否以-d分离模式启动无关:

`docker-compose up -d`

或:

`docker-compose up`

使用后者,您将直接在容器日志中看到每个更改。

检查您的容器是否已启动:

docker ps -a

如果没有启动,则开始:

docker container start CONTAINER_NAME

容器PORTS 属性如下所示:

0.0.0.0:5433->5432/tcp, :::5433->5432/tcp

这意味着:容器使用端口5433 用于Docker 主机(Linux),然后可以在端口5432 找到Docker 容器(Linux)。

在 Windows 上使用 psql 连接到 Docker 容器

之后,您可以在 Windows 上打开 psql,在简单测试阶段,您通常只需要在每个菜单点按 Enter,除了您输入 5433 的端口以连接到 Docker 主机(Linux):

Server [localhost]:
Database [postgres]:
Port [5432]: 5433
Username [postgres]:
Passwort für Benutzer postgres:
psql (13.3, Server 10.3)
Warnung: Konsolencodeseite (850) unterscheidet sich von der Windows-
         Codeseite (1252). 8-Bit-Zeichen funktionieren möglicherweise nicht
         richtig. Einzelheiten finden Sie auf der psql-Handbuchseite unter
         »Notes for Windows users«.
Geben Sie »help« für Hilfe ein.

postgres=#

然后您将在 postgres shell 中,\l 将显示您在容器的 postgres 中,而不是在 Windows postgres 中,因为它将具有容器的数据库。就我而言,我使用 docker-compose 文件添加了数据库 db,它是:

postgres=# \l
                                 Liste der Datenbanken
   Name    | Eigent³mer | Kodierung | Sortierfolge | Zeichentyp |  Zugriffsprivilegien
-----------+------------+-----------+--------------+------------+-----------------------
 db        | postgres   | UTF8      | en_US.utf8   | en_US.utf8 |
 postgres  | postgres   | UTF8      | en_US.utf8   | en_US.utf8 |
 template0 | postgres   | UTF8      | en_US.utf8   | en_US.utf8 | =c/postgres          +
           |            |           |              |            | postgres=CTc/postgres
 template1 | postgres   | UTF8      | en_US.utf8   | en_US.utf8 | =c/postgres          +
           |            |           |              |            | postgres=CTc/postgres
(4 Zeilen)

虽然我的 Windows 本地 PostgreSQL 安装中有不同的数据库。

例如,您现在可以连接到db 数据库:

\c db

创建一个空表:

CREATE TABLE "test" (

);

并显示表格:

\dt

db=#建表test(); 创建表 db=#\dt 关系列表 架构 |姓名 |类型 |本征三聚体 --------+----------------+---------+------------ 公共 |测试 |表 | D b (1 泽勒)

在 Linux 容器上使用 psql 检查新表

同时,由于您现在已经从外部更改了容器,因此该表将在容器中可用。在 WSL 的普通 Linux 终端中,运行:

docker exec -it CONTAINER_ID_OR_NAME psql -U postgres -W -d db

这会导致:

Password for user postgres:
psql (10.3)
Type "help" for help.

db=# \dt
             List of relations
 Schema |      Name      | Type  |  Owner
--------+----------------+-------+----------
 public | test           | table | postgres
(1 row)

关于-W的旁注

顺便说一句,使用-W 似乎被推荐为PostgreSQL docs 所说的:

强制 psql 在连接到数据库之前提示输入密码。

这个选项不是必须的,因为 psql 会自动提示 如果服务器要求密码验证,则输入密码。然而, psql 将浪费一次连接尝试,发现服务器想要 密码。在某些情况下,值得输入 -W 以避免额外的 连接尝试。

-W 后面不期望有值,即纯文本密码不跟在-W 后面。相反,它只是表明用户必须输入密码才能连接,从而避免了一次无用的连接尝试。

奇怪的是,在密码提示下,我也可以输入错误的密码或根本没有密码,但仍然进入数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    相关资源
    最近更新 更多