从外部连接Docker容器中的Postgresql

535

我在一个Docker容器的服务器上安装了PostgreSQL。如何从外部,也就是我的本地计算机连接到它?需要应用哪些设置来允许连接?


1
你使用了哪个命令来启动PostgreSQL?你可以暴露一个端口并映射它。 - lvthillo
1
请参考此链接:https://reachmnadeem.wordpress.com/2020/06/02/running-postgresql-database-in-docker-and-connecting-from-host-outside-container/,了解如何在Docker中运行PostgreSQL数据库并从容器外部的主机连接。 - craftsmannadeem
18个回答

671

您可以通过以下方式运行Postgres(映射端口):

docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres

现在您已将容器的5432端口映射到服务器的5432端口。-p <host_port>:<container_port>。现在,您可以通过public-server-ip:5432访问您的Postgres。

测试方法: 运行Postgres数据库(参考上方命令)。

docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
05b3a3471f6f        postgres            "/docker-entrypoint.s"   1 seconds ago       Up 1 seconds        0.0.0.0:5432->5432/tcp    some-postgres

进入您的容器并创建一个数据库:

docker exec -it 05b3a3471f6f bash
root@05b3a3471f6f:/# psql -U postgres
postgres-# CREATE DATABASE mytest;
postgres-# \q

前往您的本地主机(其中您拥有某些工具或psql客户端)。

psql -h public-ip-server -p 5432 -U postgres

(密码 mysecretpassword)

postgres=# \l

                             List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 mytest    | 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   

所以你正在从本地主机访问在服务器上运行的docker中的数据库。

这篇文章中详细解释了如何操作。


1
@Tjorriemorrie 你确定你的Postgres正在本地运行吗?也许尝试使用127.0.0.1而不是localhost,但对我来说它有效。 - lvthillo
12
获取您的公网IP地址(OSX):ifconfig -u | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | head -1 - Paul
13
在我找到的所有与PostgreSQL/Docker相关的帖子中,这是最有用的之一。谢谢。 - rg88
2
@GarouDan 如果您不想映射端口,但仍希望从主机访问postgres容器,则需要在主机网络上部署容器,如下所示:docker run --net=host --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres - lvthillo
2
退出psql的命令是\q(仅供像我这样的新手参考) - Dirk Schumacher
显示剩余5条评论

196

我成功在Linux上运行了它

  1. 运行Docker的Postgres - 确保端口已发布,我使用alpine因为它很轻便。

docker run --rm -P -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD="1234" --name pg postgres:alpine
  • 使用另一个终端,使用postgres uri从主机访问数据库

  • psql postgresql://postgres:1234@localhost:5432/postgres
    
    对于Mac用户,将psql替换为pgcli。

    36
    很高兴有人回答了如何在不进入容器的情况下连接。谢谢。 - PabTorre
    13
    不应该使用 sudo 命令来运行你的容器。 - Russ Bateman

    109

    您也可以通过执行docker exec命令来访问,方法如下:

    $ docker exec -it postgres-container bash
    
    # su postgres
    
    $ psql
    
    或者
    $ docker exec -it postgres-container psql -U postgres
    

    8
    这是一个指令,用于在命令行界面中登录到PostgreSQL数据库的默认用户postgres账户。 - Maryna Shabalina
    su postgres 是什么意思? - Breno
    2
    @Breno su postgres 的意思是:切换用户到postgres用户。 - vab2048
    2
    运行得非常好。首先,您需要获取Docker Postgres的容器ID,使用命令“docker ps -a”,然后使用该命令的containerID:docker exec -it container_ID psql -U postgres。 - MMEL
    在执行 su postgres 后使用 psql 命令。 - Jagruti

    71

    我正在使用Docker容器中的Django和PostgreSQL。在docker-compose文件中,添加以下内容:

    db:
        image: postgres:10-alpine
        environment:
            - POSTGRES_DB=app
            - POSTGRES_USER=postgres
            - POSTGRES_PASSWORD=supersecretpassword
        ports:
            - "6543:5432"
    

    这个 ports 设置使用端口 6543 (只需要与 5432 不同即可),可以被本地机器访问。我自己使用 DBeaver 进行连接。这将防止您的应用请求和本地机器请求之间的端口冲突。

    起初,我收到一条消息,说端口5432正在使用中(这是由django应用程序使用的),所以我无法通过pgAdmin或DBeaver进行访问。


    15
    我认为这是最有帮助的。对于使用docker-compose的人来说,这似乎是最好的选择。 - David Frick
    2
    我可以确认这一点,同时这个看似奇怪的设置使用一个与标准不同的主机端口号,而标准的5432端口号可以在容器中继续使用而不会有任何影响。我曾经安装了一个Windows版的PostgreSQL,它占用了需要连接到Docker主机的5432端口号,请参见从Windows Docker主机连接到dockerized postgres? - questionto42
    然后你使用哪个IP地址进行连接? - Fabien Snauwaert
    这对我起作用了。端口5432不起作用。不确定为什么,因为该端口显然未被占用或在我的计算机上排除,但是,将其切换到我选择的随机端口最终成为了我的解决方案。 - Xevion
    有点令人惊讶的是,当映射到已连接的主机端口时,Docker镜像可以构建和运行;这实际上意味着主机无法连接到Postgres镜像。 - dragonfly02
    这个对我来说完全没问题。我使用docker-compose在docker上创建了一个postgres。我一直在尝试不同的配置来连接它,但是这个配置起作用了。 - Pogryziony

    25

    我知道这有点晚了,如果你像@Martin一样使用docker-compose:

    这些片段可以帮助我连接到容器内的psql

    docker-compose run db bash

    root@de96f9358b70:/# psql -h db -U root -d postgres_db

    由于我没有50个声望,所以无法发表评论。希望这能帮到你。


    2
    Op想要从外部连接。 - avizzzy
    @avizzzy 这只是对 Ashutosh Gupta 所说的另一种选择。本应该在那里也发表评论。虽然我并不在意,但生活中应该保持一致,对吧? - Rishabh Anand
    1
    @RishabhAnand 从现在开始你会的 :) - user12504785

    23

    我假设您希望能够在从外部连接到容器时查看其中的数据。要实现这一点,您需要在 postgres 映像上持久保存数据。

    如果没有持久化数据,您将不得不重复第一次进行的所有步骤。
    步骤3、5、6、7和8直接回答了您的问题。

    以下是我在 Windows 10 powershell 上执行的整个过程的详细概述(在 Linux 和 macOS 中的命令也相同):

    步骤1:以非管理员模式启动 powershell

    步骤2:下载 postgres docker 镜像:

    docker pull postgres:latest
    

    步骤 3:以分离模式启动 Docker 容器,并通过创建卷并将其绑定到目标位置,持久化数据在 postgres 镜像上
    (注意: 默认情况下,5432 是默认端口,但为了防止来自客户端如 pgadmin, dbeaver 等的连接错误,请明确指定)

    docker run --name postgres-test -e POSTGRES_PASSWORD=password \
        -p 5432:5432 -v postgres-data:/var/lib/postgresql/data \
        -d postgres:latest
    
    第四步:检查正在运行的容器的状态
    docker ps -a
    

    第5步:以交互模式进入container_name
    (注意:如果在安装过程中选择了Linux容器,可以在此执行诸如lspwd等命令)

    docker exec -it postgres-test psql -U postgres
    

    步骤 6:创建示例数据。此时,您可以按照以下方式使用psql命令:

    # CREATE DATABASE test;
    # \c test
    # CREATE TABLE test_table(something int);
    # INSERT INTO test_table VALUES (123);
    # SELECT * FROM test_table;
    # \q
    
    第七步:打开一个数据库客户端应用程序,如pgadmin或dbeaver,并在连接字段中输入以下内容:
    Host: localhost
    Database: test
    User: postgres
    Password: password
    
    第八步:输入查询
    SELECT * FROM test_table
    
    在查询编辑器中,您应该能够看到输出123

    我完全按照这个步骤操作,但是当我在 DBeaver 中输入详细信息时,它显示测试数据库不存在。 - J Hubbard

    21

    我已经在主机上运行了Postgres,并且不希望允许来自网络的连接,因此我在容器中运行了一个临时的Postgres实例并仅用两行创建了数据库:

    # Run PostgreSQL
    docker run --name postgres-container -e POSTGRES_PASSWORD=password -it -p 5433:5432 postgres
    
    # Create database
    docker exec -it postgres-container createdb -U postgres my-db
    

    1
    如果您想创建一个默认的单个数据库,您还可以添加:-e POSTGRES_DB=my-db来创建名为my-db的数据库,而不是postgres。 - framp

    20

    由于某种原因,5432端口似乎受到了保护。我将我的端口配置从5432:5432更改为5416:5432,并使用以下命令成功地连接到您的postgres数据库以访问其docker容器外部的内容

    psql -h localhost -p 5416 -U <my-user> -d <my-database>
    

    这对我有效,但我在互联网上没有找到解释。你找到了吗? - negas
    6
    @negas,你可能已经在本地主机上运行了postgres服务,它已经绑定到了localhost:5432端口,这将阻止你使用它。在容器中将不同的主机端口映射到默认端口5432是一个不错的解决方案;或者你可以停止主机上的postgres服务,但也许它正在被你需要的其他东西使用。 - Davos
    移除端口后,与我一起工作。 - HassanBakri

    19
    连接到运行中的本地容器postgres
    1. 安装 psql

      brew search postgres
      brew install postgresql
      
    2. 启动 Docker

      docker run --name postgres -e POSTGRES_DB=users \
        -e POSTGRES_USER=john \
        -e POSTGRES_PASSWORD=password \
        -p 5432:5432 -d postgres
      
    3. 连接到数据库

      psql --host=localhost --username=john --dbname=users
      

    该psql命令在Windows上无法工作。出现身份验证失败错误。 - Andy N

    17

    要从本地主机连接,您需要添加“--net host”:

    docker run --name some-postgres --net host -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres
    

    您可以通过以下方式直接从本地访问服务器,无需使用exec:

    psql -h localhost -p 5432 -U postgres
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,