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:
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
?
I found the solution, thanks to Nick! (and another friend) Answer below.
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.
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.
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.
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.
Strangely enough, the solution ended up being to change
volumes: - ./postgres-data:/var/lib/postgresql
to
volumes: - ./postgres-data:/var/lib/postgresql/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.
docker volume inspect pgdata // output will be [ { "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/pgdata/_data", "Name": "pgdata", "Options": {}, "Scope": "local" } ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With