I\'m using the official Postgres Docker image trying to customize its configuration. For this purpose, I use the command sed
to change max_connections
Using docker compose you can mount a volume with postgresql.auto.conf
.
Example:
version: '2'
services:
db:
image: postgres:10.9-alpine
volumes:
- postgres:/var/lib/postgresql/data:z
- ./docker/postgres/postgresql.auto.conf:/var/lib/postgresql/data/postgresql.auto.conf
ports:
- 5432:5432
I was also using the official image (FROM postgres
)
and I was able to change the config by executing the following commands.
The first thing is to locate the PostgreSQL config file. This can be done by executing this command in your running database.
SHOW config_file;
I my case it returns /data/postgres/postgresql.conf
.
The next step is to find out what is the hash of your running PostgreSQL docker container.
docker ps -a
This should return a list of all the running containers. In my case it looks like this.
...
0ba35e5427d9 postgres "docker-entrypoint.s…" ....
...
Now you have to switch to the bash inside your container by executing:
docker exec -it 0ba35e5427d9 /bin/bash
Inside the container check if the config is at the correct path and display it.
cat /data/postgres/postgresql.conf
I wanted to change the max connections from 100 to 1000 and the shared buffer from 128MB to 3GB. With the sed command I can do a search and replace with the corresponding variables ins the config.
sed -i -e"s/^max_connections = 100.*$/max_connections = 1000/" /data/postgres/postgresql.conf
sed -i -e"s/^shared_buffers = 128MB.*$/shared_buffers = 3GB/" /data/postgres/postgresql.conf
The last thing we have to do is to restart the database within the container. Find out which version you of PostGres you are using.
cd /usr/lib/postgresql/
ls
In my case its 12
So you can now restart the database by executing the following command with the correct version in place.
su - postgres -c "PGDATA=$PGDATA /usr/lib/postgresql/12/bin/pg_ctl -w restart"
The postgres:9.4
image you've inherited from declares a volume at /var/lib/postgresql/data
. This essentially means you can't copy any files to that path in your image; the changes will be discarded.
You have a few choices:
You could just add your own configuration files as a volume at run-time with docker run -v postgresql.conf:/var/lib/postgresql/data/postgresql.conf ...
. However, I'm not sure exactly how that will interact with the existing volume.
You could copy the file over when the container is started. To do that, copy your file into the build at a location which isn't underneath the volume then call a script from the entrypoint or cmd which will copy the file to correct location and start postgres.
Clone the project behind the Postgres official image and edit the Dockerfile to add your own config file in before the VOLUME is declared (anything added before the VOLUME instruction is automatically copied in at run-time).
Pass all config changes in command option in docker-compose file
like:
services:
postgres:
...
command:
- "postgres"
- "-c"
- "max_connections=1000"
- "-c"
- "shared_buffers=3GB"
- "-c"
...
I looked through all answers and there is another option left. You can change your CMD value in docker file (it is not the best one, but still possible way to achieve your goal).
Basically we need to
Docker file example:
FROM postgres:9.6
USER postgres
# Copy postgres config file into container
COPY postgresql.conf /etc/postgresql
# Override default postgres config file
CMD ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
Though I think using command: postgres -c config_file=/etc/postgresql/postgresql.conf
in your docker-compose.yml
file proposed by Matthias Braun is the best option.
When you run the official entrypoint (A.K.A. when you launch the container), it runs initdb
in $PGDATA
(/var/lib/postgresql/data
by default), and then it stores in that directory these 2 files:
postgresql.conf
with default manual settings.postgresql.auto.conf
with settings overriden automatically with ALTER SYSTEM commands.The entrypoint also executes any /docker-entrypoint-initdb.d/*.{sh,sql}
files.
All this means you can supply a shell/SQL script in that folder that configures the server for the next boot (which will be immediately after the DB initialization, or the next times you boot the container).
Example:
conf.sql
file:
ALTER SYSTEM SET max_connections = 6;
ALTER SYSTEM RESET shared_buffers;
Dockerfile
file:
FROM posgres:9.6-alpine
COPY *.sql /docker-entrypoint-initdb.d/
RUN chmod a+r /docker-entrypoint-initdb.d/*
And then you will have to execute conf.sql
manually in already-existing databases. Since configuration is stored in the volume, it will survive rebuilds.
Another alternative is to pass -c
flag as many times as you wish:
docker container run -d postgres -c max_connections=6 -c log_lock_waits=on
This way you don't need to build a new image, and you don't need to care about already-existing or not databases; all will be affected.