简体   繁体   English

从 Windows Docker 主机连接到 dockerized postgres

[英]Connect to dockerized postgres from Windows Docker host

my setup is Docker for Windows (Version 18.09.2) on a Windows 10 Pro machine with installed postgres (not a database, only the command line tools).我的设置是 Docker for Windows(版本 18.09.2)在安装了 postgres(不是数据库,只有命令行工具)的 Windows 10 Pro 机器上。

I run the official postgres image from docker hub with我从 docker 中心运行官方 postgres 图像

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

Afterwards I am able to connect via之后我可以通过连接

docker exec -it <docker-id> bash

and run并运行

psql -U postgres

Everything works fine.一切正常。 Now I want to connect from my host.现在我想从我的主机连接。 I call我打电话

psql -h <local-ip> -U postgres

and got并得到

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?

I am pretty sure, the database could be accessed.我很确定,可以访问数据库。 Because if I change the IP I receive因为如果我更改我收到的 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?

Has anyone any clue how I can fix this issue?有谁知道我该如何解决这个问题? Or what I am doing wrong?或者我做错了什么?

It took me quite some time to find out how to enter the container's databases from a normal psql prompt on Windows. This was due to an additional local Windows installation.我花了很长时间才弄清楚如何从 Windows 上的正常 psql 提示符进入容器的数据库。这是由于额外的本地 Windows 安装。


Creating a Docker container (Linux) without a port clash at 54325432上创建一个没有端口冲突的 Docker 容器 (Linux)

The structure of the port parameter (both in docker run and in docker-compose ) is:端口参数的结构(在docker rundocker-compose中)是:

<docker_host_port_on_linux>:<docker_container_port_on_linux>

See Connecting to Postgresql in a docker container from outside .请参阅从外部连接到 docker 容器中的 Postgresql The <host_port> is the port that you can find on Windows to connect to the container's port. <host_port>是您可以在 Windows 上找到的用于连接容器端口的端口。 And the core trick that seems to be needed here is to avoid a port clash which is in another answer of the same thread .这里似乎需要的核心技巧是避免同一线程的另一个答案中的端口冲突。

If you take 5432:5432 , this might conflict with a local installation of postgres on Windows which uses port 5432 as a standard.如果您使用5432:5432 ,这可能会与 Windows 上使用端口5432作为标准的 postgres 本地安装冲突。 You can find out about such a conflict by opening psql, logging in with the menu (in the standard test phase, you will probably just need to press Enter at any menu point) and then print all available databases with \l .您可以通过打开 psql、使用菜单登录(在标准测试阶段,您可能只需要在任何菜单点按 Enter)然后使用\l打印所有可用数据库来了解此类冲突。 If these are the databases of your local Windows installation, you know that you have to use another port when using docker.如果这些是您本地 Windows 安装的数据库,您知道在使用 docker 时必须使用另一个端口。

If there is a conflict between the ports, use a new port for the Docker host, either with parameter如果端口之间存在冲突,请为 Docker 主机使用新端口,或者使用参数

-p 5433:5432

or when using docker-compose, the file needs to have:或者当使用 docker-compose 时,文件需要有:

ports:
    - "5433:5432"

It is not relevant whether you start in -d detached mode or not:是否以-d分离模式启动是无关紧要的:

`docker-compose up -d`

or:或者:

`docker-compose up`

With the latter, you will just see every change directly in the container log.使用后者,您将直接在容器日志中看到每个更改。

Check that your container is started:检查您的容器是否已启动:

docker ps -a

If it is not started, start with:如果未启动,请从以下内容开始:

docker container start CONTAINER_NAME

The container PORTS attribute will look as follows:容器PORTS属性如下所示:

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

That means: the container uses port 5433 for the Docker host (Linux) which can then find the Docker container (Linux) at port 5432 .这意味着:容器将端口5433用于 Docker 主机(Linux),然后可以在端口5432找到 Docker 容器(Linux)。

Use psql on Windows to connect to the Docker container在Windows上使用psql连接Docker容器

After this, you can open psql on Windows, in the easy test phase you will usually just need to press enter for every menu point except for the port where you enter 5433 to connect to the Docker host (Linux):在此之后,您可以在 Windows 上打开 psql,在简单测试阶段,除了您输入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=#

and then you will be in the postgres shell and \l will show that you are in the container's postgres and not in the Windows postgres, since it will have the databases of the container.然后你将在 postgres shell 中并且\l将显示你在容器的 postgres 中而不是在 Windows postgres 中,因为它将具有容器的数据库。 In my case, I added the database db with the docker-compose file, and there it is:在我的例子中,我添加了带有 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)

While I had different databases on my Windows local PostgreSQL installation.虽然我的 Windows 本地 PostgreSQL 安装上有不同的数据库。

For example, you could now connect to the db database:例如,您现在可以连接到db数据库:

\c db

Create an empty table:创建一个空表:

CREATE TABLE "test" (

);

and show the tables:并显示表格:

\dt

db=# create table test (); db=#创建表test(); CREATE TABLE db=# \dt Liste der Relationen Schema | CREATE TABLE db=# \dt 列出关系模式 | Name |名称 | Typ |类型 | Eigent³mer --------+----------------+---------+------------ public | Eigent³mer --------+----------------+--------+------------ public | test |测试 | Tabelle |表格 | db (1 Zeile)分贝 (1 Zeile)

Use psql on the Linux container to check the new table在 Linux 容器上使用 psql 检查新表

At the same time, this table will be available in the container since you have now changed the container from outside.同时,该表将在容器中可用,因为您现在已经从外部更改了容器。 In the normal Linux terminal of your WSL, run:在 WSL 的正常 Linux 终端中,运行:

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

Which leads to:这导致:

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)

Sidenote about -W关于-W的旁注

By the way, using -W seems recommended as the PostgreSQL docs say about it:顺便说一下,使用-W似乎被推荐为PostgreSQL 文档所说的那样:

Force psql to prompt for a password before connecting to a database.强制 psql 在连接到数据库之前提示输入密码。

This option is never essential, since psql will automatically prompt for a password if the server demands password authentication.这个选项从来都不是必需的,因为如果服务器要求密码验证,psql 会自动提示输入密码。 However, psql will waste a connection attempt finding out that the server wants a password.然而,psql 将浪费一次连接尝试来发现服务器需要密码。 In some cases it is worth typing -W to avoid the extra connection attempt.在某些情况下,值得键入 -W 以避免额外的连接尝试。

-W does not expect a value after it, that is, the plain text password does not follow the -W . -W不期望它后面有值,即明文密码不跟在-W之后。 Instead, it just shows that the user will have to enter a password to connect, which is avoiding one useless connection attempt.相反,它只是表明用户必须输入密码才能连接,这避免了一次无用的连接尝试。

Strangely, at the password prompt, I could also enter a wrong password or none at all and still enter the database.奇怪的是,在提示密码时,我也可以输入错误的密码或根本不输入密码,但仍会进入数据库。

To connect to a container from your host you have to publish ports to your host. 要从主机连接到容器,必须将端口发布到主机。 That is done using port publishing and -p option : 这是使用端口发布和-p选项完成的:

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

Notice the -p option. 注意-p选项。 Now when you will be trying to connect to port 5432 on your localhost, the traffic will be redirected to the port 5432 of the container. 现在,当您尝试连接到本地主机上的端口5432时,流量将被重定向到容器的端口5432

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM