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

Abh*_*nyu 7 database django postgresql docker

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

  • 整个网络在一个容器中关联事物。
  • 数据库,即另一个Postgres

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

docker run --name postgres -it -e POSTGRES_USER=username -e POSTGRES_PASSWORD=mysecretpassword postgres
Run Code Online (Sandbox Code Playgroud)

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

docker exec -it postgres /bin/bash
root@ae052fbce400:/# psql -U psql
Run Code Online (Sandbox Code Playgroud)

在我得到的Psql Shell中,我正在创建数据库,DBNAME并授予它所有特权username

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'DBNAME',
        'USER': 'username',
        'PASSWORD': 'mysecretpassword',
        'HOST': 'postgres',
        'PORT': 5432
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的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"
Run Code Online (Sandbox Code Playgroud)

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

web_1       | django.db.utils.OperationalError: FATAL:  password authentication failed for user "username"
Run Code Online (Sandbox Code Playgroud)

Our*_*han 10

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

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

码头工人组成

  • 小心,这将删除您本地的所有图像。 (3认同)
  • 非常感谢你救了我的命哈哈 (2认同)

tru*_*512 6

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

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

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

version: '3'

services:
    web:
        image: 1ce04167758d
        command: python manage.py runserver
        volumes:
            - .:/code
        ports:
            - "8000:8000"
Run Code Online (Sandbox Code Playgroud)

在您的配置中,您应该更改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 Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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