Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dockerized postgresql with volumes

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.

like image 208
Chris Avatar asked Nov 23 '17 14:11

Chris


People also ask

Can you Dockerize database?

Docker is great for running databases in a development environment! You can even use it for databases of small, non-critical projects which run on a single server.

What is postgres volume?

A named volume called postgres is referenced; Docker will either create it or reattach the volume if it already exists. You should use a volume to store your database outside the container. Without one you'll use your data when the container stops. PostgreSQL listens on port 5432 by default.

Can volume be shared across multiple containers?

For multiple containers writing to the same volume, you must individually design the applications running in those containers to handle writing to shared data stores to avoid data corruption. After that, exit the container and get back to the host environment.


1 Answers

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.

like image 168
yamenk Avatar answered Sep 25 '22 05:09

yamenk