0

I'm aware of the following solution for the no pg_hba.conf entry for host error: connect to PostgreSQL server: FATAL: no pg_hba.conf entry for host

But I wonder why this error happens when using Postgres environment variable POSTGRES_PASSWORD_FILE in Docker, and not when setting the password directly with an environment variable such as POSTGRES_PASSWORD.

Here are the most useful bits of code. If you want to see a complete example, please take a look at this repository.

This version will trigger the error:

services:
  database:
    image: postgres:10
    volumes:
      - ./pass/db/db_pass:/run/secrets/db_pass:ro
      - data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_pass

While this version will work fine:

services:
  database:
    image: postgres:10
    volumes:
      - data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=db_password

The ./pass/db/db_pass file contains exactly the same password: db_password.

Basically, the only thing that changes between the two configuration is that setting the password for the database container is 1) done with an environment variable POSTGRES_PASSWORD and 2) done reading the file pointed by POSTGRES_PASSWORD_FILE, file which is bind-mounted inside the container as read-only.

If we look at the Postgres' entrypoint, POSTGRES_PASSWORD_FILE is used to fill POSTGRES_PASSWORD: https://github.com/docker-library/postgres/blob/master/10/docker-entrypoint.sh#L8-L24.

# usage: file_env VAR [DEFAULT]
#    ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
#  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
    local var="$1"
    local fileVar="${var}_FILE"
    local def="${2:-}"
    if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
        echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
        exit 1
    fi
    local val="$def"
    if [ "${!var:-}" ]; then
        val="${!var}"
    elif [ "${!fileVar:-}" ]; then
        val="$(< "${!fileVar}")"
    fi
    export "$var"="$val"
    unset "$fileVar"
}

I don't get why then Postgres throws this no pg_hba.conf entry for host error if the database has been correctly created with the given password.

Looking at the entry point, the configuration should be the exact same, but I verified both with the command docker-compose -f no-file.yml run --rm database /bin/bash -c 'cat $PGDATA/pg_hba.conf' and the line host all all all md5 does not appear in the configuration using POSTGRES_PASSWORD_FILE.

Why does the default configuration changes when we make use of the POSTGRES_PASSWORD_FILE variable, and how to fix this elegantly? Do I have to provide a custom Postgres configuration file as described in https://hub.docker.com/_/postgres/, section "Database configuration"?

0

It was a permission issue.

database_1   | /usr/local/bin/docker-entrypoint.sh: line 19: /run/secrets/db_pass: Permission denied

My password file had -rw------- permissions. Since the docker-entrypoint.sh script sets the -e option, it was exiting early, right after this error, preventing to append the host all all all md5 line to pg_hba.conf.

I added r for group and others, as well as r-x for group and others on its parent directory. That fixed the issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.