Postgres 9.1 的 Docker 容器未将端口 5432 暴露给主机
Posted
技术标签:
【中文标题】Postgres 9.1 的 Docker 容器未将端口 5432 暴露给主机【英文标题】:Docker container for Postgres 9.1 not exposing port 5432 to host 【发布时间】:2016-06-26 00:23:45 【问题描述】:我正在尝试使用 Docker 容器来运行 PostgreSQL 服务器,并从我的主机与其连接。
我的配置是:
主机:Mac OS X 10.10.5 Docker 1.10.1我已经这样做了:
第 1 步:为永久 postgres 数据创建一个卷
docker volume create --name postgres_data
第 2 步:启动 postgres 实例
更新:按照cmets的建议,我在运行容器时指定了端口映射
docker run --name my_postgres_container -e POSTGRES_PASSWORD=my_password -v postgres_data:/var/lib/postgresql/data -p 5432:5432 -d postgres:9.1
第 3 步:通过以下方式连接到 Docker 实例:
docker run -it --link my_postgres_container:postgres --rm postgres:9.1 sh -c 'exec psql -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres'
但我想通过以下方式连接到该实例:
psql -h localhost -p 5432 -U postgres
就像我在我的主机上本地安装了 Postgres。
问题是5432端口没有暴露。所以,我无法连接它:
sudo lsof -i -P | grep -i "listen"
--> 5432 端口未打开
更新 2:更陌生。我也这样做了:
停止 Docker。然后,在我的主机上运行一个普通的 PostgreSQL 9.4.4 实例(这里不涉及 docker,只是在我的 Mac OS X 主机上运行 postgres,侦听端口 5432)。一切正常:
sudo lsof -i -P | grep -i "postgres"
postgres 14100 jorge 6u IPv4 0x780274158cebef01 0t0 TCP localhost:5432 (LISTEN)
我可以毫无问题地连接到我的本地 postgres 实例(查看命令的输出:是为我的主机 Mac OS X 编译的 postgres):
psql -h localhost -U postgres -c "select version()"
version
---------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0, compiled by Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn), 64-bit
(1 row)
现在是有趣的部分。我再次启动我的 Docker 实例,在主机 PostgreSQL 实例运行时。
开始了! (它不应该)。我什至可以使用 docker run 连接...
docker run -it --link my_postgres_instance:postgres --rm postgres:9.1 sh -c 'exec psql -h "$POSTGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U postgres'
如果我现在运行 select version(),它显示 postgres 在我的 docker 实例中运行,同时 postgres 在我的主机中运行,在 docker 之外,使用相同的 5432 端口。 (看输出,是为 Debian 编译的 postgres,postgres:9.1 容器内的操作系统)
postgres=# select version();
version
------------------------------------------------------------------------------------------------
PostgreSQL 9.1.20 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
(1 row)
为什么?
这有意义吗?我的最终目标是在另一个 Docker 容器中运行 Django 应用程序并连接到我的 Postgres 实例。我怎么能那样做?
【问题讨论】:
【参考方案1】:现在是 2018 年,我也遇到了类似的问题。对我来说,解决方案似乎是 docker 的道具顺序。例如这导致没有端口被暴露;
docker run -d --name posttest postgres:alpine -e POSTGRES_PASSWORD=fred -p 5432:5432
虽然这工作正常(图像暴露端口 5432 符合预期);
docker run --name posttest -d -p 5432:5432 -e POSTGRES_PASSWORD=fred postgres:alpine
【讨论】:
有人能解释一下为什么这个顺序很重要吗?谢谢 我的理解是,在镜像名称之后传递的args被定向到容器中运行的命令,而在镜像名称之前传递的args被传递给Docker 哇...它对我有用。万分感谢。我的mac上docs.docker.com/samples/library/postgres上的示例(查找2019may04)不起作用。我错过了什么吗?【参考方案2】:您的 docker 主机是一个虚拟机,它有自己的 IP 地址。 您可以通过输入以下命令来检测此 IP 地址:
docker-machine ip
答案将类似于 192.168.99.100
当您使用 -p 5432:5432 开关映射端口后,您将能够使用提到的 IP 地址从您的开发机器上使用任何工具连接到 postgres。
【讨论】:
这是唯一对我有用的答案。看起来如果存在虚拟机,Docker 会将端口映射到这台机器而不是主机系统。【参考方案3】:使用-p <host_port>:<container_port>
:使用正确的端口映射运行 postgre 映像:
docker run --same-options-as-step-one -d -p 5432:5432 postgres:9.1
【讨论】:
谢谢!我已经做到了。但仍然无法使用 psql 连接。端口 5432 没有被暴露,或者我不知道如何连接。我主机的 psql 程序运行正常(我可以连接到其他主机,但不能连接到我的容器)docker port <container_name>
显示什么?
它应该打印类似5432/tcp -> 0.0.0.0:5432
5432/tcp -> 0.0.0.0:5432。尝试使用 -h 0.0.0.0 -p 5432。出现连接被拒绝错误:服务器是否正在运行...?我真的可以只使用普通的 psql 进行连接,还是需要运行另一个容器来测试 psql?因为官方文档没有使用正常的psql命令:hub.docker.com/_/postgres
你应该可以使用普通的psql
..你试过-h 127.0.0.1 -p 5432
吗?【参考方案4】:
我能够使用容器 IP 或主机 IP 进行连接,但 localhost (127.0.0.1) 除外。
获取容器 ID 运行
docker ps
找到所需的容器 id 并运行
docker inspect --format='range .NetworkSettings.Networks.IPAddressend' <container_id>
端口必须暴露。
这是一个 docker-compose.yml 的示例,它启动了两个容器 postgres 和 adminer,这是一个数据库管理工具,您可以使用它来连接到 postgres:
version: '3'
services:
adminer:
image: adminer
restart: always
ports:
- 8080:8080
postgres:
image: postgres:11.4-alpine
restart: always
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
【讨论】:
我得到了一个不同于 0.0.0.0 和 127.0.0.1 的 IP @mad_ 没关系,一定是容器IP。如果 postgres 端口被暴露,您应该能够使用该 IP 连接到它。【参考方案5】:我遇到了类似的问题。我的问题只是 0.0.0.0 没有映射到 localhost 所以我只需要添加到 psql
psql --host=0.0.0.0
这是假设
docker port <container name>
输出
5432/tcp -> 0.0.0.0:5432
【讨论】:
【参考方案6】:我在使用 Lubuntu 的 VMWare 虚拟机中工作时遇到了类似的问题。 VM 已暂停,然后重新启动。 PostgreSQL Docker 容器已正确映射并在 localhost:5432 上侦听,但我总是得到:
psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
重启虚拟机解决了我的问题。
【讨论】:
【参考方案7】:其他答案有效,但不要解释它们为什么有效。
给定命令:
psql -h localhost -p 5432:5432 -U postgres
localhost
实际上是一个特殊值,它告诉 psql 寻找 unix 套接字连接,而不是通过 TCP。我们不能使用 unix 套接字连接到 docker 服务。
像这样更改命令,通过强制 TCP 来修复它:
psql -h 127.0.0.1 -p 5432:5432 -U postgres
只要您docker run ... -p 5432:5432 ...
,它就会起作用。指定docker-machine ip
返回的 IP 也会强制使用 TCP,因此也可以。
【讨论】:
【参考方案8】:试试这个来安装postgresql
docker run --name postgres -d -p 5432:5432 -e POSTGRES_PASSWORD=fred postgres:alpine
或更改端口主机 Heree (mac)
docker run --name postgres -d -p 5436:5432 -e POSTGRES_PASSWORD=fred postgres:alpine
提示: 安装 pgadmin4
docker run -p 5050:80 -e "PGADMIN_DEFAULT_EMAIL=name@example.com" -e "PGADMIN_DEFAULT_PASSWORD=admin" -d dpage/pgadmin4
【讨论】:
以上是关于Postgres 9.1 的 Docker 容器未将端口 5432 暴露给主机的主要内容,如果未能解决你的问题,请参考以下文章
centos7下安装docker(9.1容器对资源的使用限制-CPU)
如何将节点 docker 容器与 postgres docker 容器连接起来
Docker - 如何在postgres容器中运行psql命令?