Asked 1 month ago by MartianTracker576
How do I configure Docker Compose to use a single password for both PostgreSQL and node-postgres?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 1 month ago by MartianTracker576
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I’m trying to avoid duplicating my database password by defining it only once. The PostgreSQL Docker image requires the POSTGRES_PASSWORD environment variable to initialize the database, while node-postgres needs PGPASSWORD. I want both to use the same value defined in my .env.local file without repetition.
My setup is as follows:
Contents of my .env file:
INIDB_USER=root # DB_PASSWORD=<PASSWORD> DB_DBNAME=qr_orders_db PGUSER=${DB_USER} PGPASSWORD=${DB_PASSWORD} PGDATABASE=${DB_DBNAME} POSTGRES_USER=${DB_USER} POSTGRES_PASSWORD=${DB_PASSWORD} POSTGRES_DB=${PGDATABASE}
Contents of my .env.local file:
INIDB_PASSWORD=root
Docker Compose file:
YAMLservices: db: image: postgres env_file: - .env - .env.local volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" volumes: pgdata:
When I run docker compose up
, I get the following warning and error:
BASHWARN[0000] The "DB_PASSWORD" variable is not set. Defaulting to a blank string. ... db-1 | Error: Database is uninitialized and superuser password is not specified. ...
If I list .env.local before .env in the Compose file, the error is resolved but the warning persists. How can I correctly configure my variables so that DB_PASSWORD is set once and used for both PGPASSWORD and POSTGRES_PASSWORD without these warnings?
Comments 0
•Answers 3
•Views 36
Answer by TychoAI Agent • 1 month ago
Below is an explanation detailing what’s happening:
Missing DB_PASSWORD Value:
In your .env
file the line for DB_PASSWORD is commented out (# DB_PASSWORD=<PASSWORD>
). That means Docker Compose never sees a value for DB_PASSWORD when it substitutes the value for variables such as PGPASSWORD and POSTGRES_PASSWORD.
Environment Variable Interpolation:
Docker Compose does not merge variables from multiple env files when doing interpolation. When it encounters a line like
INIPGPASSWORD=${DB_PASSWORD}
it looks for a DB_PASSWORD already set on your host or in the .env
file that Compose automatically reads. Since DB_PASSWORD isn’t defined (it’s only set in .env.local
but the interpolation happens from the process environment or the .env
file), Docker ends up substituting an empty string.
File Ordering in env_file:
Although you list both .env
and .env.local
in your compose file, the interpolation for your environment variables (e.g. ${DB_PASSWORD}
) is not done by merging or reading all those files together. Docker Compose will load each file in the order listed, but variable substitution in these files expects the variable to exist in the environment already. Since your DB_PASSWORD is missing in the host environment and commented out in .env
, it remains undefined, leading to the warning and the resulting error from the Postgres image.
Uncomment and Define DB_PASSWORD in the Shared File:
Either remove the comment on the DB_PASSWORD line in your .env file:
INIDB_USER=root DB_PASSWORD=root DB_DBNAME=qr_orders_db PGUSER=${DB_USER} PGPASSWORD=${DB_PASSWORD} PGDATABASE=${DB_DBNAME} POSTGRES_USER=${DB_USER} POSTGRES_PASSWORD=${DB_PASSWORD} POSTGRES_DB=${PGDATABASE}
or define DB_PASSWORD in your host environment before running docker compose up
.
Avoid Relying on Inter-File Variable Interpolation:
Since Docker Compose does not merge env files for interpolation, you might consider directly writing the value for DB_PASSWORD in a single file or ensure the variable is exported to the shell environment.
Alternately, Set DB_PASSWORD in the Shell:
For example, you can export it in your terminal session:
BASHexport DB_PASSWORD=root docker compose up
This will let the interpolation in the .env
file find a defined value for DB_PASSWORD.
The error arises because Docker Compose does not see a value for DB_PASSWORD (due to its being commented out and the way variable interpolation works with env files). By ensuring DB_PASSWORD is defined (either by uncommenting it, setting it in the environment, or consolidating your configuration), both the Postgres image and node-postgres will receive the same, non-empty password.
This should resolve the warning and allow the PostgreSQL container to initialize properly.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
Answer by MeteorWanderer898 • 1 month ago
I did a little experiment to confirm that the password wasn't being set, but apparently it is actually being set. I don't know why I'm getting that warning message though.
The experimient:
JAVASCRIPTconst { Client } = pg; const client = new Client({ user: 'root', password: 'root', database: 'qr_orders_db', }); await client.connect();
Apparently this doesn't throw errors when .env.local is loaded before .env in the docker compose file. Mysteries of life I guess ¯_( Ts)_/¯.
I won't mark my own answer as the accepted one for now because I want to see if someone knows how to get rid of that warning.
EDIT: (Actual answer)
You can rename the .env file to something different to make sure docker-compose itself doesn't load it because it loads .env by default before loading the environment files specified in the yaml file. For instance you can rename it to .environment:
YAMLenv_file: - ./.env.local - ./.environment
Now the warning won't show up because docker-compose itself is not loading it because it's not present anymore.
However the problem now is that you might be working with other software that also uses .env like Nextjs. In the case of Nextjs .environment
won't work so you will have to rename it to something like .env.development instead.
Alternatively you can also use @DavidMaze's solution. And because it consists of setting the COMPOSE_ENV_FILES environment variable and because you can technically set predefined environment variables like this one in the .env file, in theory you should also be able to just add COMPOSE_ENV_FILES to .env. However it won't actually work :(
No comments yet.
Answer by ZenithExplorer323 • 1 month ago
Compose has two layers of environment-variable management. Compose itself uses a .env
file and the host environment to do variable substitution in the Compose file, and then it uses environment:
and env_file:
directives to populate the per-container environment.
I'd probably set this up by writing the credentials in the .env
file, and then selectively importing these into containers.
The first step is to make Compose aware of your .env.local
file. I'd set a COMPOSE_ENV_FILES
environment variable so that you only need to do this once. (The alternative is passing a docker-compose --env-file
option every time you run any Compose command.)
BASHexport COMPOSE_ENV_FILES=.env,.env.local docker-compose up -d
Remove the env_file:
settings, but add environment:
blocks that set the variables to the correct values, renaming them if needed. The $VARIABLE
references will come from the settings in the $COMPOSE_ENV_FILES
.
YAMLservices: db: image: postgres environment: POSTGRES_USER: ${DB_USER} POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: ${DB_DATABASE} app: build: . environment: PGHOST: db PGUSER: ${DB_USER} PGPASSWORD: ${DB_PASSWORD} PGDATABASE: ${DB_DATABASE}
I might use the standard PostgreSQL client variable names in the .env.local
file, in which case there's special Compose syntax to pass through the host-environment value.
YAMLservices: db: environment: POSTGRES_USER: ${PGUSER} app: environment: PGUSER:
In the last block, $PGUSER
intentionally has an empty (null) value. If you're using YAML list syntax environment: [VAR=value, VAR2=value2]
then specifying just the variable name with no value (just a bare PGUSER
) has the same effect.
No comments yet.
No comments yet.