Docker的postgres容器的密码验证失败 [英] Password authentication failed for Docker's postgres container

查看:904
本文介绍了Docker的postgres容器的密码验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对我的Django项目进行docker化。为此,我试图将整个项目分为两个部分




  • 将整个Web相关的内容放在一个容器中。

  • 数据库,即Postgres在另一个



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

  docker run --name postgres -it -e POSTGRES_USER =用户名-e POSTGRES_PASSWORD = mysecretpassword postgres 

此postgres实例开始运行时,我使用以下命令输入了shell postgres实例:

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

在我得到的Psql Shell中,我正在创建名为 DBNAME 的数据库,并将所有特权授予用户名;



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

  DATABASES = {
'默认':{
'ENGINE':'django.db.backends.postgresql_ psycopg2',
'NAME':'DBNAME',
'USER':'用户名',
'PASSWORD':'mysecretpassword',
'HOST':'postgres' ,
'PORT':5432
}
}

此处是我的docker-compose.yml文件

 服务:
网站:
图片:1ce04167758d #image构建webapp容器
命令:python manage.py runserver
卷:
-。:/ code
端口:
- 8000:8000
depends_on :
-postgres
postgres:
图片:postgres
env_file:
-.env
暴露:
- 5432

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

  web_1 | django.db.utils.OperationalError:致命:用户用户名的密码身份验证失败


解决方案

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



方案1-使用单独的数据库



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

 版本:'3'

服务:
网站:
图像:1ce04167758d
命令:python manage.py runserver
卷:
-。:/ code
端口:
- 8000:8000

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

 数据库= {
'默认':{
'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应用,它将连接。



进一步阅读postgres env变量



方案2-使用组合数据库



这里有很多解释,因为您必须设置一个入口点,它将等待直到数据库完全初始化为止。但是我已经就如何做到这一点写了一个逐步的答案在堆栈上



除了数据库服务外,您的情况基本相同。您只需稍作更改即可保留当前的撰写内容:

 版本:'3'

服务:
网站:
图像:1ce04167758d
命令:python manage.py runserver
数量:
-。:/ code
端口:
- 8000:8000
取决于:
-postgres
入口点:[ ./docker-entrypoint.sh]

postgres:
图片:postgres
env_file:
-.env

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



我可以看到您已经定义了一个入口点-我建议从<$ c中删除此入口点 $ c> Dockerfile ,将其移至 compose 文件,并将其与我在引用链接中描述的内容合并。这是在商业/大型环境中的常见做法,因为您可能有许多入口点,或者/并且作为您的入口点可能不希望在构建时运行-就像我建议的那样。



我已经删除了数据库端口映射,因为如果不需要-如果只有 web

使用上面的配置,您的Django配置将是完美的。



从评论中编辑



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

  $ ifconfig 

主机上的地址将提供您的本地IP地址( 192。 xxx 10.xxx ),并且此IP是您在设置中指定的IP p>

I am trying to dockerize my Django project. For this purpose, I am trying to divide the whole project into 2 parts

  • The whole web related things in one container.
  • Database i.e Postgres in another

I am creating the Postgres database container using command:

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

When this postgres instance started running I entered the shell postgres instance using:

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

Inside Psql shell that i got, I am creating the Database named DBNAME and granted all the privileges to username;

Database settings inside the webapp container is:

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

Here is my docker-compose.yml file

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"

When I ran docker-compose up I am getting the following error:-

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

解决方案

This is because you created two database services. One manually via docker run and one via docker-compose. Unfortunately both unusable, meaning they'd have to be reconfigured in order to cooperate.

Scenario 1 - using a separate DB

You should remove the database definition from compose file - so that it looks like this:

version: '3'

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

And in your config you should change postgres to your host machine - for example 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
    }
}

Then, run a separate database service just like you did, via the run command, but exposing a port publicly.

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

When it finished initializing and when you finish adding databases and users you can fire up your Django app and it'll connect.

further reading on postgres env variables

Scenario 2 - using composed database

There's a lot of explaining here, as you have to set up a entrypoint that will wait until the DB is fully initialized. But I've already written a step by step answer on how to do it here on stack

Your situation is basically the same except for the DB service. You leave your compose nearly as it is now, with a little changes:

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

I've added a entrypoint that is supposed to wait until your DB service completes initialization (for instructions on how to set it up you should refer to the link I provided earlier on).

I can see you've defined a entrypoint already - I'd suggest removing this entrypoint from Dockerfile, move it to the compose file and merge it with what I've described in the referred link. It's a common practice in commercial/bigger environments, as you might have many entrypoints, or/and as your entrypoint might not be intended to run while building - like the one I suggest is.

I've removed DB port mapping as you shouldn't expose services if there's no need - if only the web service is supposed to use the DB, then we shouldn't expose the DB for other possibilities.

With the above configuration, your Django configuration would be perfectly fine.

edit from comments

The 0.0.0.0 IP provided for postgres states that the server will listen on all incoming connections. It means that in settings.py you should specify not the 0.0.0.0 address but a address of the host on which your service runs - in your case I guess it's run on your computer - so simply running:

$ ifconfig

on your host will give your your local ip address ( 192.x.x.x or 10.x.x.x ) and this IP is what you specify in settings

这篇关于Docker的postgres容器的密码验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆