PGDATA forced to default location
Closed this issue · 6 comments
Bug report
- I confirm this is a bug with Supabase, not with my own application.
- I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
The image forces PGDATA to be the default location: /var/lib/postgresql/data and fail it is overriden.
If the user defines PGDATA to another location, it is ignored and the container will fail starting.
Here is an output with PGDATA=/var/lib/postgresql/data/pgdata (NOTE the extra non standard /pgdata at the end):
2025-05-27 09:00:49.140 UTC [1] FATAL: "/var/lib/postgresql/data" is not a valid data directory
To Reproduce
You can test using docker and:
docker run --rm -it \
-e PGDATA=/data \
-e POSTGRES_PASSWORD=password \
supabase/postgres:17.4.1.036
It will fail mentioning:
2025-05-27 09:25:05.745 UTC [49] FATAL: data directory "/var/lib/postgresql/data" does not exist
which should not be relevant since we want to use /data.
Expected behavior
The user can point to a custom PGDATA and the container starts.
Using the original postgres image works fine:
docker run --rm -it \
-e PGDATA=/data \
-e POSTGRES_PASSWORD=password \
postgres:latest
System information
- version: supabase-postgres:17.4.1.036
but the issue is not specific to this version.
I am confused about this line: https://github.com/supabase/postgres/blob/develop/Dockerfile-15#L229
docker run --rm -it \
-e PGDATA=/data \
-e POSTGRES_PASSWORD=password \
supabase/postgres:17.4.1.036
=> FAIL
docker run --rm -it \
-e PGDATA=/data \
-e POSTGRES_PASSWORD=password \
supabase/postgres:17.4.1.036 postgres
=> WORKS
Provinding postgres effectively "removes" the surprising default CMD and its "-D", "/etc/postgresql".
Why would /etc/postgresql be passed as data folder ?
Just read through the Dockerfile, so I might be missing something.
All the configs are copied from ansible/files to /etc/postgresql. https://github.com/supabase/postgres/blob/develop/Dockerfile-15#L162
And in this postgresql.conf file which is copied to the image, data_directory is hard coded to /var/lib/postgresql/data.
In the image CMD ["postgres", "-D", "/etc/postgresql"], so even when you specify PGDATA env var postgres is still looking in /var/lib/postgresql/data
docker run --rm -it
-e PGDATA=/data
-e POSTGRES_PASSWORD=password
supabase/postgres:17.4.1.036 postgres
=> WORKS
I'm assuming that when you override the image args, you setup postgres container with default postgres config so it works but you lose the supabase customized config.
The issue I see is that if a user provides PGDATA=/foo/bar it is not expected that postgres uses /etc/postgresql as datadir and I did not spot the reason why it reports missing /var/lib/postgresql/data.
But that's an interesting finding and that means the issue is how the postgres.conf is generated/pathed.
I feel it would make more sense to bring whatever config into the PGDATA specified by the user when the DB is initialized but I am surely missing something.
and I did not spot the reason why it reports missing /var/lib/postgresql/data
Let me clarify.
postgres entrypoint is docker-entrypoint.sh. db directory is created by calling docker_create_db_directories. This function is imported from the upstream postgres repo's docker-entrypoint.sh
If you look at docker_create_db_directories signature, it runs command mkdir -p $PGDATA. This will create directory as specified in PGDATA env. By default, this is /var/lib/postgresql/data. If you override it (e.g., with PGDATA: /data), then only /data will be created.
Now, in supabase postgres repo's Dockerfile the CMD is set to ["postgres", "-D", "/etc/postgresql"].
postgres loads config from /etc/postgresql/postgresql.conf. Inside that file, data_directory is still set to /var/lib/postgresql/data, which hasn’t been created - because PGDATA pointed elsewhere (/data), and that’s the only directory the entrypoint script created. Thus /var/lib/postgresql/data is missing.
The simplest solution is to modify the image’s entrypoint to update the data_directory inside postgresql.conf dynamically
Here is an example. I just used sed to modify the data_directory in postgresql.conf inside container and everything works fine. I had v15 image downloaded on system. Will work the same with v17
services:
db:
image: supabase/postgres:15.8.1.060
ports:
- 5432:5432
entrypoint: /bin/bash -c "
sed -i \"s|data_directory.*|data_directory = '/data'|\" /etc/postgresql/postgresql.conf && \
exec docker-entrypoint.sh postgres -D /etc/postgresql
"
environment:
POSTGRES_PASSWORD: password
PGDATA: /data
volumes:
- ./data:/dataClosing. PR's welcome if anyone has a proposition for desired changes.