Docker 的 postgres 容器的密码验证失败

Posted

技术标签:

【中文标题】Docker 的 postgres 容器的密码验证失败【英文标题】:Password authentication failed for Docker's postgres container 【发布时间】:2018-10-24 14:26:11 【问题描述】:

我正在尝试 dockerize 我的 Django 项目。为此,我试图将整个项目分成两部分

一个容器中的整个网络相关的东西。 数据库,即另一个数据库中的 Postgres

我正在使用命令创建 Postgres 数据库容器:

docker run --name postgres -it -e POSTGRES_USER=username -e POSTGRES_PASSWORD=mysecretpassword postgres

当这个 postgres 实例开始运行时,我使用以下命令进入了 shell postgres 实例:

docker exec -it postgres /bin/bash
root@ae052fbce400:/# psql -U psql

在我得到的 Psql shell 中,我正在创建名为 DBNAME 的数据库并将所有权限授予username

webapp 容器内的数据库设置为:

DATABASES = 
    'default': 
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'DBNAME',
        'USER': 'username',
        'PASSWORD': 'mysecretpassword',
        'HOST': 'postgres',
        'PORT': 5432
    

这是我的 docker-compose.yml 文件

services:
    web:
        image: 1ce04167758d  #image build of webapp container
        command: python manage.py runserver
        volumes:
            - .:/code
        ports:
            - "8000:8000"
        depends_on:
            - postgres
    postgres:
        image: postgres
        env_file:
            - .env
        expose:
            - "5432"

当我运行docker-compose up 时,我收到以下错误:-

web_1       | django.db.utils.OperationalError: FATAL:  password authentication failed for user "username"

【问题讨论】:

【参考方案1】:

这是因为您创建了两个数据库服务。一种通过docker run 手动,另一种通过docker-compose。不幸的是,两者都无法使用,这意味着它们必须重新配置才能合作。

场景 1 - 使用单独的数据库

您应该从撰写文件中删除数据库定义 - 使其看起来像这样:

version: '3'

services:
    web:
        image: 1ce04167758d
        command: python manage.py runserver
        volumes:
            - .:/code
        ports:
            - "8000:8000"

在您的配置中,您应该将 postgres 更改为您的主机 - 例如 192.168.1.2

DATABASES = 
    'default': 
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'itoucan',
        'USER': 'mannu',
        'PASSWORD': 'mysecretpassword',
        'HOST': '192.168.1.2',
        'PORT': 5432
    

然后,像你一样通过run 命令运行一个单独的数据库服务,但公开一个端口。

docker run --name postgres -it -p 5432:5432 -e POSTGRES_USER=mannu -e POSTGRES_PASSWORD=mysecretpassword postgres

当它完成初始化并完成添加数据库和用户时,你可以启动你的 Django 应用程序,它就会连接。

further reading on postgres env variables

场景 2 - 使用组合数据库

这里有很多解释,因为你必须设置一个entrypoint,它会等到数据库完全初始化。但是我已经写了一个关于如何做的一步一步的答案here on stack

你的情况基本一样,除了数据库服务。您几乎保持现在的作曲,只是稍作改动:

version: '3'

services:
    web:
        image: 1ce04167758d
        command: python manage.py runserver
        volumes:
            - .:/code
        ports:
            - "8000:8000"
        depends_on:
            - postgres
        entrypoint: ["./docker-entrypoint.sh"]

    postgres:
        image: postgres
        env_file:
            - .env

我添加了一个entrypoint,它应该等到您的数据库服务完成初始化(有关如何设置它的说明,您应该参考我之前提供的链接)。

我可以看到您已经定义了一个入口点 - 我建议从 Dockerfile 中删除此 entrypoint,将其移动到 compose 文件并将其与我在引用链接中描述的内容合并。这是商业/更大环境中的常见做法,因为您可能有很多 entrypoints,或者/和您的 entrypoint 可能不打算在构建时运行 - 就像我建议的那样。

我已经删除了数据库端口映射,因为如果不需要,您不应该公开服务 - 如果只有 web 服务应该使用数据库,那么我们不应该公开数据库以获得其他可能性。

有了上面的配置,你的 Django 配置就完美了。

从 cmets 编辑

为 postgres 提供的0.0.0.0 IP 表明服务器将侦听所有传入连接。这意味着在settings.py 中,您应该指定而不是 0.0.0.0 地址,而是您的服务运行所在主机的地址 - 在您的情况下,我猜它是在您的计算机上运行的 - 所以只需运行:

$ ifconfig

在您的主机上将提供您的本地 IP 地址(192.x.x.x10.x.x.x),此 IP 是您在 settings 中指定的地址

【讨论】:

我遵循了你的所有程序,但是当我运行 Postgres 实例时,我得到了日志LOG: listening on IPv4 address "0.0.0.0", port 5432`` but when I used that IP i.e 0.0.0.0 in settings.py, I am getting 无法连接到服务器:连接被拒绝服务器是否在主机“0.0.0.0”上运行并接受端口 5432 上的 TCP/IP 连接?无法连接```我该如何解决这个问题? 我在回答的末尾添加了对您的问题的解释。 很高兴听到,保重 ;)【参考方案2】:

我尝试了各种步骤,但这是解决我问题的步骤。

docker stop $(docker ps -qa) && docker system prune -af --volumes

码头工人组成

【讨论】:

非常感谢你救了我的命哈哈 小心,这将清除您本地的所有图像。

以上是关于Docker 的 postgres 容器的密码验证失败的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose 安装postgres(设置默认用户名,密码,暴露端口)

无法从 golang 连接到 docker postgres 容器

docker postgres使用

如何将节点 docker 容器与 postgres docker 容器连接起来

Docker - 如何在postgres容器中运行psql命令?

docker-compose:nodejs容器不与postgres容器通信