Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to persist data in a dockerized postgres database using volumes

My docker compose file has three containers, web, nginx, and postgres. Postgres looks like this:

postgres:   container_name: postgres   restart: always   image: postgres:latest   volumes:     - ./database:/var/lib/postgresql   ports:     - 5432:5432 

My goal is to mount a volume which corresponds to a local folder called ./database inside the postgres container as /var/lib/postgres. When I start these containers and insert data into postgres, I verify that /var/lib/postgres/data/base/ is full of the data I'm adding (in the postgres container), but in my local system, ./database only gets a data folder in it, i.e. ./database/data is created, but it's empty. Why?

Notes:

  • This suggests my above file should work.
  • This person is using docker services which is interesting

UPDATE 1

Per Nick's suggestion, I did a docker inspect and found:

    "Mounts": [         {             "Source": "/Users/alex/Documents/MyApp/database",             "Destination": "/var/lib/postgresql",             "Mode": "rw",             "RW": true,             "Propagation": "rprivate"         },         {             "Name": "e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35",             "Source": "/var/lib/docker/volumes/e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35/_data",             "Destination": "/var/lib/postgresql/data",             "Driver": "local",             "Mode": "",             "RW": true,             "Propagation": ""         }     ], 

Which makes it seem like the data is being stolen by another volume I didn't code myself. Not sure why that is. Is the postgres image creating that volume for me? If so, is there some way to use that volume instead of the volume I'm mounting when I restart? Otherwise, is there a good way of disabling that other volume and using my own, ./database?

UPDATE 2

I found the solution, thanks to Nick! (and another friend) Answer below.

like image 687
Alex Lenail Avatar asked Jan 13 '17 15:01

Alex Lenail


People also ask

How do you persist data in a database container?

With the database being a single file, if we can persist that file on the host and make it available to the next container, it should be able to pick up where the last one left off. By creating a volume and attaching (often called “mounting”) it to the directory the data is stored in, we can persist the data.

Which is used to persist the database container data?

Volumes are the preferred way to persist data in Docker containers and services. Some use cases for volumes include: Sharing data among multiple running containers. If you don't explicitly create it, a volume is created the first time it is mounted into a container.

What is postgres volume?

The Postgres official image, however, comes with a VOLUME predefined in its image description. This means that when you run a PostgreSQL image as a container, it creates a volume for itself and stores data in there.

Which command allows containers to run with persistent volumes?

Docker has an option to allow specific folders in a container to be mapped to the normal filesystem on the host. This allows us to have data in the container without making the data part of the Docker image, and without being bound to AUFS.


2 Answers

Strangely enough, the solution ended up being to change

volumes:   - ./postgres-data:/var/lib/postgresql 

to

volumes:   - ./postgres-data:/var/lib/postgresql/data 
like image 184
Alex Lenail Avatar answered Sep 29 '22 16:09

Alex Lenail


You can create a common volume for all Postgres data

 docker volume create pgdata 

or you can set it to the compose file

   version: "3"    services:      db:        image: postgres        environment:          - POSTGRES_USER=postgres          - POSTGRES_PASSWORD=postgress          - POSTGRES_DB=postgres        ports:          - "5433:5432"        volumes:          - pgdata:/var/lib/postgresql/data        networks:          - suruse    volumes:       pgdata: 

It will create volume name pgdata and mount this volume to container's path.

You can inspect this volume

docker volume inspect pgdata  // output will be [     {         "Driver": "local",         "Labels": {},         "Mountpoint": "/var/lib/docker/volumes/pgdata/_data",         "Name": "pgdata",         "Options": {},         "Scope": "local"     } ] 
like image 31
Nishchit Avatar answered Sep 29 '22 16:09

Nishchit