Postgresql – dockerized postgresql with volumes

dockerpostgresqlvolumes

i am relatively new to docker. I'd like to set up a postgres database but I wonder how to make sure that the data isn't being lost if I recreated the container.

Then I stumbled over named volumes (not bind volumes) and how to use them.
But… in a Dockerfile you can't use named volumes. E.g. data:/var/lib etc.
As I understood using a Dockerfile it's always an anonymous volume.
So every single time I'd recreate a container it would get its
own new volume.

So here comes my question:

Firstly: how do I make sure, if the container get's updated or recreated that the postgres database from within the new container references to the same data and not losing the reference to the previously created anonymous volume.

Secondly: how does this work with a yml file?
is it possible to reference multiple replicas of such a database container to one volume? (High Availability Mode)?

It would really be great if someone could get me a hint or best practices.

Thank you in advance.

Best Answer

Looking at the Dockerfile for Postgres, you see that it declares a volume instruction:

VOLUME /var/lib/postgresql/data

Everytime you run a new Postgres container, without specifying a --volume option, docker automatically creates a new volume. The volume is given a random name.

You can see all volumes by running the command:

docker volume ls

You can also inspect the files stored on the host by the volume, by inspecting the host path using:

docker volume inspect <volume-name>

So when you don't specify the --volume option for the run command, docker create volumes for all volumes declared in the Dockerfile. This is mainly a safety if you forget to name your volume and the data shouldn't be lost.

Firstly: how do I make sure, if the container get's updated or recreated that the postgres database from within the new container references to the same data and not losing the reference to the previously created anonymous volume.

If you want docker to use the same volume, you need to specify the --volume option. Once specified, docker won't create a new volume and it will simply mount the existing volume onto the specified folder in the docker command.

As a best practice, name your volumes that have valuable data. For example:

docker run --volume postgresData:/var/lib/postgresql/data ...

If you run this command for the first time the volume postgresData will be created and will backup /var/lib/postgresql/data on the host. The second time you run it the same data backed up on the host will be mounted onto the container.

Secondly: how does this work with a yml file? is it possible to reference multiple replicas of such a database container to one volume?

Yes, volumes can be shared between multiple containers. You can mount the same volume onto multiple containers, and the containers will use the same files. Docker compose allows you to do that ...

However, beware that volumes are limited to the host they were created. When running containers on multiple machines, the volume needs to be accessible from all the machines. There are ways/tools to achieve that but they are a bit complex. This is still a limitation to be addressed in Docker.