我试图使用Docker容器来运行PostgreSQL服务器,并从我的主机连接它。
我的配置是:
我已经这样做了:
第1步:为永久性postgres数据创建一个卷
docker volume create --name postgres_data
第2步:启动postgres实例
UPDATE :正如评论中所建议的那样,我在运行容器时指定了端口映射
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)
现在有趣的部分。当主机PostgreSQL实例运行时,我再次启动我的Docker实例,。
它开始了! (而且它不应该)。我甚至可以使用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(),它会显示在我的docker实例中运行的postgres,同时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实例连接。我怎么能这样做?
答案 0 :(得分:9)
使用-p <host_port>:<container_port>
使用正确的端口映射运行postgre图像:
docker run --same-options-as-step-one -d -p 5432:5432 postgres:9.1
答案 1 :(得分:7)
您的泊坞主机是一台虚拟机,拥有自己的IP地址。 您可以通过输入以下命令来检测此IP地址:
docker-machine ip
答案将是 192.168.99.100
使用-p 5432:5432交换机映射端口后,您可以使用所提到的IP地址通过dev机器上的任何工具连接到postgres。
答案 2 :(得分:1)
我有一个类似的问题。我的问题很简单,就是0.0.0.0没有映射到本地主机,所以我只需要添加到psql
psql --host=0.0.0.0
这是推测
docker port <container name>
输出
5432/tcp -> 0.0.0.0:5432
答案 3 :(得分:1)
我能够使用容器IP或主机IP(本地主机(127.0.0.1)除外)进行连接。
要获取容器ID,请运行
docker ps
找到所需的容器ID并运行
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <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
答案 4 :(得分:1)
在使用Lubuntu的VMWare虚拟机中工作时,我遇到了类似的问题。 VM已暂停,然后重新启动。 PostgreSQL Docker容器已正确映射并在localhost:5432上侦听,但我总是得到:
#include <iostream>
using namespace std;
void reverse(int num) {
int rem = 0;
while (num != 0) {
rem = rem * 10 + num % 10;
num = num / 10;
}
cout << rem << endl;
}
int main() {
int num;
while (num != 0) {
cin >> num;
reverse(num);
if (num == 0)
break;
}
return 0;
}
重启虚拟机解决了我的问题。
答案 5 :(得分:0)
其他答案有效,但不解释为什么有效。
给出命令:
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,因此也可以使用。