Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Password authentication failed for Docker's postgres container

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"
like image 561
Abhimanyu Avatar asked May 14 '18 20:05

Abhimanyu


People also ask

How do I fix Postgres password authentication failed?

Restart the PostgreSQL service from the Services control panel ( start->run->services. msc ) Connect using psql or pgAdmin4 or whatever you prefer. Run ALTER USER postgres PASSWORD 'fooBarEatsBarFoodBareFoot'

What is the default Postgres password?

1, the default Postgres database password is postgres . Type the new password for the selected user type. Type the password again to confirm it. Click Save Configuration.


2 Answers

I tried various steps but this is the one which solved my problem.

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

docker-compose up

like image 65
OurangZeb Khan Avatar answered Oct 13 '22 16:10

OurangZeb Khan


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

like image 6
trust512 Avatar answered Oct 13 '22 14:10

trust512