【问题标题】:Connect to postgres in docker container from host machine从主机连接到 docker 容器中的 postgres
【发布时间】:2018-11-28 02:56:29
【问题描述】:

如何从主机连接到 docker 中的 postgres?

docker-compose.yml

version: '2'

networks:
    database:
        driver: bridge
services:
    app:
        build:
            context: .
            dockerfile: Application.Dockerfile
        env_file:
            - docker/Application/env_files/main.env
        ports:
            - "8060:80"
        networks:
           - database
        depends_on:
            - appdb

    appdb:
        image: postdock/postgres:1.9-postgres-extended95-repmgr32
        environment:
            POSTGRES_PASSWORD: app_pass
            POSTGRES_USER: www-data
            POSTGRES_DB: app_db
            CLUSTER_NODE_NETWORK_NAME: appdb
            NODE_ID: 1
            NODE_NAME: node1
        ports:
            - "5432:5432"
        networks:
            database:
                aliases:
                    - database

docker-compose ps

           Name                          Command               State               Ports
-----------------------------------------------------------------------------------------------------
appname_app_1     /bin/sh -c /app/start.sh         Up      0.0.0.0:8060->80/tcp
appname_appdb_1   docker-entrypoint.sh /usr/ ...   Up      22/tcp, 0.0.0.0:5432->5432/tcp

从容器我可以成功连接。来自 app 容器和 db 容器。

在容器内运行 psql 的 dbs 和用户列表:

# psql -U postgres
psql (9.5.13)
Type "help" for help.

postgres=# \du
                                       List of roles
    Role name     |                         Attributes                         | Member of
------------------+------------------------------------------------------------+-----------
 postgres         | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 replication_user | Superuser, Create role, Create DB, Replication             | {}
 www-data         | Superuser                                                  | {}

postgres=# \l
                                       List of databases
      Name      |      Owner       | Encoding |  Collate   |   Ctype    |   Access privileges
----------------+------------------+----------+------------+------------+-----------------------
 app_db         | postgres         | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres       | postgres         | UTF8     | en_US.utf8 | en_US.utf8 |
 replication_db | replication_user | 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
(5 rows)

DB 图像不是官方的 postgres 图像。但是 GitHub 中的 Dockerfile 看起来还不错。

来自 DB 容器的 cat /var/lib/postgresql/data/pg_hba.conf:

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     postgres                                trust
#host    replication     postgres        127.0.0.1/32            trust
#host    replication     postgres        ::1/128                 trust

host all all all md5
host replication replication_user 0.0.0.0/0 md5

我尝试了两个用户都没有运气

$ psql -U postgres -h localhost
psql: FATAL:  role "postgres" does not exist
$ psql -h localhost -U www-data appdb -W
Password for user www-data:
psql: FATAL:  role "www-data" does not exist

看起来在我的主机上,该端口上已经运行了 PSQL。如何查看?

【问题讨论】:

  • 你在哪个操作系统上试用这个?
  • 我在 OSX 上运行它
  • 如何检查您的主机中是否已经有 postgresql 在同一端口上运行?为什么不停止容器并运行 psql?

标签: postgresql docker docker-compose


【解决方案1】:

我相信问题是你在本地机器上的端口 5432 上运行了 postgres。 可以通过将 docker 容器的端口 5432 映射到主机中的另一个端口来解决问题。 这可以通过在 docker-compose.yml 中进行更改来实现

改变

"5432:5432" 

"5433:5432"

重启 docker-compose

现在 docker 容器 postgres 在 5433 上运行。(本地安装的 postgres 在 5432 上) 您可以尝试连接到 docker 容器。

psql -p 5433 -d db_name -U user -h localhost

【讨论】:

  • 谢谢!我遇到了与原始问题相同的问题。你的回答对我有用!
  • 谢谢。你启发了我。但就我而言,要使其正常工作,我必须将 psql 的主机指定为0.0.0.0。比如psql -p 5433 -h 0.0.0.0 -U postgres
  • 我可以确认,由于5432 是本地安装使用的默认端口,通常只需更改两个端口号中的第一个即可,因为端口冲突。这两个端口中的第一个用于 Linux 上的 Docker host_port。如果该端口已被占用,则无法使用该端口访问主机。同样的技巧在 docker-compose 中也有效,参见 Connect to dockerized postgres from Windows Docker host?https://stackoverflow.com/a/55259785/11154841
【解决方案2】:

我在 Ubuntu 16.04 上运行了这个

$ psql -h localhost -U www-data app_db
Password for user www-data:
psql (9.5.13)
Type "help" for help.

app_db=# \du
                                       List of roles
    Role name     |                         Attributes                         | Member of
------------------+------------------------------------------------------------+-----------
 postgres         | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 replication_user | Superuser, Create role, Create DB, Replication             | {}
 www-data         | Superuser                                                  | {}

下面从我的mac到运行docker的VM(192.168.33.100是docker VM的IP地址)

$ psql -h 192.168.33.100 -U www-data app_db
Password for user www-data:
psql (9.6.9, server 9.5.13)
Type "help" for help.

app_db=# \du
                                       List of roles
    Role name     |                         Attributes                         | Member of
------------------+------------------------------------------------------------+-----------
 postgres         | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 replication_user | Superuser, Create role, Create DB, Replication             | {}
 www-data         | Superuser                                                  | {}

他们都为我工作。

VM 上的 PSQL 版本

$ psql --version
psql (PostgreSQL) 9.5.13

Mac 上的 PSQL 版本

$ psql --version
psql (PostgreSQL) 9.6.9

【讨论】:

  • 这对我不起作用。看起来我的主机上的那个端口上已经运行了 PSQL。如何查看?
  • 要检查使用的端口,请使用以下命令之一 lsof -i -P -n | grep 5432ss -tulwn | grep 5432netstat -tulpn | grep 5432。建议在这些命令中使用sudo,我相信最后两个命令在 Mac 上不可用。
【解决方案3】:

我在基本 OS 5.0 上运行 postgres 10 官方 docker 容器时遇到了同样的问题。我能够使用正在运行的容器的 ip 从主机连接。

sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name/id

获取ip后测试: psql -h 172.17.0.2 -U postgres

【讨论】:

    【解决方案4】:

    我相信您在pg_hba.conf 中遇到了问题。在这里,您指定了 1 个可以访问的主机 - 127.0.0.1/32。

    你可以改成这样:

    # IPv4 local connections:
    host    all             all             0.0.0.0/0            md5
    

    这将确保您的主机(完全不同的 IP)可以连接。

    要检查是否有一个 postgresql 实例已经在运行,你可以这样做 netstat -plnt | grep 5432。如果您从中得到任何结果,您可以获取 PID 并验证进程本身。

    【讨论】:

    • 感谢netstat | grep 5432 提示。我用它来发现我确实已经在本地运行了 postgres
    【解决方案5】:

    我有一个相对相似的设置,以下对我来说可以在主机上打开一个psql 会话到 docker postgres 实例中: docker-compose run --rm db psql -h db -U postgres -d app_development

    地点:

    • db 是容器的名称
    • postgres 是用户名
    • app_development 是数据库的名称

    所以对你来说,它看起来像docker-compose run --rm appdb psql -h appdb -U www-data -d app_db

    【讨论】:

    • 我需要从主机访问
    • @mef_ 我更新了我的答案以更具体地说明命令的作用。如果你尝试一下,具体是什么不起作用?
    【解决方案6】:

    由于您在 OSX 中运行它,您可以随时使用预装的 Network Utility 应用在您的主机上运行 Port Scan 并确定 postgres服务器正在运行(如果是,在哪个端口上)

    但我认为您的主机上没有运行一个。问题是 Postgres 默认在 5432 上运行,而您尝试运行的 docker-compose 文件将 db 容器暴露在同一端口上,即 5432。如果 Postgres 服务器已经在您的主机上运行,​​那么 Docker 会尝试将容器暴露给已被使用的端口,从而产生错误。

    另一个可能的解决方案:
    从这个answer 可以看出,mysql 打开一个带有localhost 的unix 套接字,而不是一个tcp 套接字。也许这里正在发生类似的事情。

    在连接到容器中的服务器时尝试使用127.0.0.1 而不是localhost

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 2018-01-09
      • 2016-07-20
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多