Saving database state from library/postgres
I understand that I can change the default folder of
postgres image to point to a volume – in which case, clearly the volume will persist. But I didn’t do that because I wanted to understand the default behavior of this image.
So I simply ran:
# in one terminal docker pull postgres # as a foreground process: docker run -P --name dev_db postgres # in another terminal docker run --rm -it --link dev_db:dev_db /bin/bash # in this container, I created some databases and added some data to them # then: # docker stop dev_db # docker commit -m "Add data" dev_db postgres_with_data
I thought as a result, the new image
postgres_with_data will contain the data I added; but it doesn’t. Shouldn’t it be saved when I commit the container? If not, where did it go, and how can I save it?
Thanks for the answers. So if I understand correctly, anything written to
/var/lib/postgresql/data after postgres Dockerfile executes
VOLUME /var/lib/postgresql/data disappears when I stop the container?
But it seems the
VOLUME command in Dockerfile is equivalent to
docker run -P --name dev_db -v $(docker volume create):/var/lib/postgresql/data postgres. But I would hope a volume created with
docker volume create doesn’t actually disappear when the container is stopped; in fact, I assume it doesn’t disappear even when the container is deleted based on the documentation:
Data volumes persist even if the container itself is deleted.
What am I missing?
3 Solutions collect form web for “Saving database state from library/postgres”
When you run a container, Docker puts a writeable file system layer on top of the image layers for that container – if you make any changes in the writeable layer and commit the container to a new image, the change you made will be persisted in the new image.
postgres image stores database files in a volume, not in the writeable layer (see the Dockerfile) – so when you alter database data then that’s outside of the container’s writeable layer and the changes don’t get persisted.
If you did this instead:
docker run --name c1 postgres touch /new.txt docker commit c1 postgres-new
postgres-new image will have the new file, because it was added to the container’s file system not to a volume.
The changes you’ve made to the db are saved in a part of the container considered ephemeral by the container, and so does not persist when you commit the image. The only way to make these changes persist is by mounting this folder on a volume and reusing whenever you run a postgres container.
I don’t know if it is too late but if you want the data to persist inside the docker container you can point the pgdata dir at anything but where it points now… thus not looking at a volume and not resetting:
docker run -e PGDATA=/var/lib/postgresql/pgdata
rather than PGDATA=/var/lib/postgresql/data
Works for me on the FROM library/postgres:9.5 repo.