I was using the Postgres:11 docker image for a while now until I noticed that next to my persistent volume mount "pg-data" (Destination: "/var/lib/postgresql/data/pgdata") there was another unnamed volume listed when doing docker inspect pgcontainer
, Destination: "/var/lib/postgresql/data":
"Mounts": [
{
"Type": "volume",
"Name": "pg-data",
"Source": "/data/docker/docker/volumes/pg-data/_data",
"Destination": "/var/lib/postgresql/data/pgdata",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "4d0ab5fd1d81b05f11805f19569e148427194ef465f0d4dc301b200b8308ada6",
"Source": "/data/docker/docker/volumes/4d0ab5fd1d81b05f11805f19569e148427194ef465f0d4dc301b200b8308ada6/_data",
"Destination": "/var/lib/postgresql/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
After further investigation, it turns out that the Dockerfile itself defines a volume mount path, and I was overriding this with my docker-compose.yml:
services:
db:
volumes:
- pg-data:/var/lib/postgresql/data/pgdata
volumes:
pg-data:
imposm-cache-data:
It appears to be a nested volume now. The data is stored in volume pg-data
, but another (unnamed) volume is always automatically created before it. It works, but this is not ideal and I'd like to fix this.
I can only come up with two solutions:
Use another container (e.g. busybox) to mount the pg-data with --volume
flag and copy to another named volume with subfolder "data", then use the new named volume with changed mount path to /var/lib/postgresql/data
Another obvious idea would be to clone the Dockerfile and create a new one without the volume.
Since that volume has about 100GB of data in it, option 1 will be kind of slow. Option 2 would mean maintaining another Docker image from now on. Both options with caveats. Is there any other approach available to restructure volumes based on a new mount path?
I'd just accept the fact of the near-empty anonymous volumes.
Docker gives you fairly few options for manipulating the contents of volumes directly, and the options you list out are pretty much the choices you have without trying to manipulate Docker internals. Of those two, forking the PostgreSQL image to remove its VOLUME
seems like a massive ongoing maintenance problem. So if you have the time and the disk space, the one-time volume copy is better.
Another option you have (and it's probably worth attempting this occasionally) is to stand up a new clean system. Install Docker on it, and start PostgreSQL with the directory/volume layout you want, but empty. Now restore this database from backup.