mahonya
mahonya

Reputation: 10055

How can I keep changes I made to Postgresql Docker container?

I'm using the official postgresql docker image to start a container.

Afterwards, I install some software and use psql to create some tables etc. I am doing this by first starting the postgres container as follows:

docker run -it  --name="pgtestcontainer" -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:9.6.6

Then I attach to this container with

docker  exec -it pgtestcontainer bash

and I install software, create db tables etc.

Afterwards, I first quit from the second terminal session (that I used to install software) and do a ctrl + c in the first one to stop the postgres container.

At this point my expectation is that if I commit this postgres image with

docker commit xyz...zxy pg-commit-test

and then run a new container based on the committed image with:

docker run -it  --name="modifiedcontainer" -e POSTGRES_PASSWORD=postgres -p 5432:5432 pg-commit-test

then I should have all the software and tables in place.

The outcome of the process above is that the software I've installed is in the modifiedcontainer but the sql tables etc are gone. So my guess is my approach is more or less correct but there is something specific to postgres docker image I'm missing.

I know that it creates the db from scratch if no external directory or docker volume is bound to /var/lib/postgresql/data but I'm not doing that and after the commit I'd expect the contents of the db to stay as they are.

How do I follow the procedure above (or the right one) and keep the changes to database(s)?

Upvotes: 2

Views: 2701

Answers (3)

mahonya
mahonya

Reputation: 10055

I solved this by passing PGDATA parameter with a value that is different than the path that is bound to docker volume as suggested in one of the responses to this question.

Upvotes: 0

Corey Taylor
Corey Taylor

Reputation: 685

The postgres Dockerfile creates a mount point at /var/lib/postgresql/data which you must mount an external volume onto if you want persistent data.

ENV PGDATA /var/lib/postgresql/data
RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
VOLUME /var/lib/postgresql/data

https://docs.docker.com/engine/reference/builder/#notes-about-specifying-volumes

You can create a volume using

docker volume create mydb

Then you can use it in your container

docker run -it --name="pgtestcontainer" -v mydb:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:9.6.6

https://docs.docker.com/engine/admin/volumes/volumes/#create-and-manage-volumes

Upvotes: 1

Kilian
Kilian

Reputation: 1781

In my opinion, the best way is to create your own image with a /docker-entrypoint-initdb.d folder and your script inside. Look How to extend this image

But without volume you can't (I think) save your datas.

Upvotes: 0

Related Questions