docker-library / postgres

Docker Official Image packaging for Postgres
http://www.postgresql.org
MIT License
2.2k stars 1.14k forks source link

Secrets file not detected on startup #1228

Closed r-xyz closed 7 months ago

r-xyz commented 7 months ago

Hi all,

I am experiencing an issue trying to use Docker Secrets with latest postgres library (alpine), using Docker Compose.

From Official Page

Docker Secrets

As an alternative to passing sensitive information via environment variables, _FILE may be appended to some of the previously listed environment variables, causing the initialization script to load the values for those variables from files present in the container. In particular, this can be used to load passwords from Docker secrets stored in /run/secrets/ files. For example: $ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd -d postgres Currently, this is only supported for POSTGRES_INITDB_ARGS, POSTGRES_PASSWORD, POSTGRES_USER, and POSTGRES_DB.

Expected behaviour

Secret shall correctly be loaded from path in POSTGRES_PASSWORD_FILE (/run/secrets/POSTGRES_PASSWORD).

Current behaviour

$ docker compose up fails with

postgres  | /usr/local/bin/docker-entrypoint.sh: line 21: "/run/secrets/POSTGRES_PASSWORD": No such file or directory

Nonetheless, the file is present and contains the password:

$ docker compose run --user 10100 postgres cat /run/secrets/POSTGRES_PASSWORD
MYPASSWORD

Steps to reproduce

compose.yaml:

services:
  postgres:
    container_name: postgres
    image: "postgres:16.2-alpine"
    volumes:
      - "./data:/var/lib/postgresql/data"
    environment:
      - POSTGRES_USER="postgres"
      - POSTGRES_PASSWORD_FILE="/run/secrets/POSTGRES_PASSWORD"
    user: "10100"
    secrets:
      - postgres-password
    restart: unless-stopped
secrets:
  POSTGRES_PASSWORD:
    file: "./.secrets/POSTGRES_PASSWORD.txt"

.secrets/POSTGRES_PASSWORD.txt:

MYPASSWORD
tianon commented 7 months ago

I believe "Docker Secrets" is still a feature that was unfortunately only implemented for Swarm (and we should probably remove that section from our documentation). :disappointed:

yosifkit commented 7 months ago

Both the docker-compose and docker stack commands support defining secrets in a compose file.

- https://docs.docker.com/engine/swarm/secrets/#defining-and-using-secrets-in-compose-files

Oh, I also wasn't aware that they both support it now.


service "postgres" refers to undefined secret postgres-password: invalid compose project

  1. either the secrets key in the postgres service is incorrect or the one defined in the global secrets section needs to be changed
    -    secrets: postgres-password
    +    secrets: POSTGRES_PASSWORD

    After swapping to the secret name, I indeed can reproduce. After looking at other things, I finally looked at the env and saw the problem:

    $ docker compose run postgres env
    ...
    POSTGRES_PASSWORD_FILE="/run/secrets/POSTGRES_PASSWORD"
    ...
    POSTGRES_USER="postgres"
    ...
    $ docker compose run postgres bash
    2e9b336075bb:/# echo $POSTGRES_PASSWORD_FILE
    "/run/secrets/POSTGRES_PASSWORD"

    So, don't put quotes here or they will be part of the literal string set in the env

    -      - POSTGRES_USER="postgres"
    -      - POSTGRES_PASSWORD_FILE="/run/secrets/POSTGRES_PASSWORD"
    +       - POSTGRES_USER=postgres
    +      - POSTGRES_PASSWORD_FILE=/run/secrets/POSTGRES_PASSWORD

    This is fine too since these quotes are part of yaml syntax so don't become part of the value:

    - "POSTGRES_PASSWORD_FILE=/run/secrets/POSTGRES_PASSWORD"