简体   繁体   中英

How to persist initial db in a docker container

How do I externalise a database from within a docker postgres:9.6 container? Starting the container with no docker volume is fine. Starting the container with a docker volume mapped to a host folder erases the database and config. I understand that this is correct docker volumee behaviour, the host folder is mounted over the top of the container folder. How to I get around this issue and map the db that is created on container start up to my host folder so that it is available when the container next starts up?

Not sure what I am doing wrong here.

docker run --name test-postgres \
-e POSTGRES_PASSWORD=test123 \
-v /home/vagrant/workspace/shared-data/postgres:/var/lib/postgresql \
-d postgres:9.6

This spins up the container and creates the DB as expected. Container result:

root@fe0e5751c98d:/var/lib/postgresql# ls -al data
total 0
drwxr-xr-x. 2 root     root      6 Jun 20 12:32 .
drwxr-xr-x. 3 postgres postgres 17 Jun 20 12:32 ..           

The mapped drive on the host has the data folder created but it is empty!

[vagrant@localhost postgres]$ ls -al
total 1
drwxrwxrwx. 1 vagrant vagrant 0 Jun 20 12:27 .
drwxrwxrwx. 1 vagrant vagrant 0 Jun 18 09:33 ..
-rwxrwxrwx. 1 vagrant vagrant 5 Jun 19 21:47 container.txt
drwxrwxrwx. 1 vagrant vagrant 0 Jun 20 12:27 data
-rwxrwxrwx. 1 vagrant vagrant 0 Jun 20 12:24 dockerhost.txt
[vagrant@localhost postgres]$ ls -al data
total 0
drwxrwxrwx. 1 vagrant vagrant 0 Jun 20 12:27 .
drwxrwxrwx. 1 vagrant vagrant 0 Jun 20 12:27 ..

HOWEVER, if I map to a folder that is not mapped by Vagrant (I am on windows) I dont lose data. So it seems that there is may be an issue between Docker mapping a folder to a Vagrant mapped folder.Spotted that the directories created by the postgres container (when not mapping to a Vagrant shared folder) on the docker host have odd permissions (owners and group).

[vagrant@localhost ~]$ ls -al
total 20
drwx------. 4 vagrant vagrant 4096 Jun 23 17:51 .
drwxr-xr-x. 3 root    root      20 May 21 20:07 ..
-rw-r--r--. 1 vagrant vagrant   18 Nov 20  2015 .bash_logout
-rw-r--r--. 1 vagrant vagrant  193 Nov 20  2015 .bash_profile
-rw-r--r--. 1 vagrant vagrant  231 Nov 20  2015 .bashrc
drwx------. 2 vagrant root      28 Jun 23 17:47 .ssh
-rw-r--r--. 1 vagrant vagrant    6 May 21 13:07 .vbox_version
drwxr-xr-x. 4 vagrant vagrant   39 Jun 23 18:01 workspace
[vagrant@localhost ~]$ ls -al workspace/
total 4
drwxr-xr-x. 4 vagrant vagrant   39 Jun 23 18:01 .
drwx------. 4 vagrant vagrant 4096 Jun 23 17:51 ..
drwxr-xr-x. 3 root    root      17 Jun 23 18:01 postgres
drwxr-xr-x. 5 vagrant vagrant   46 Jun 23 17:51 shared-data
[vagrant@localhost ~]$ ls -al workspace/postgres/
total 4
drwxr-xr-x.  3 root              root      17 Jun 23 18:01 .
drwxr-xr-x.  4 vagrant           vagrant   39 Jun 23 18:01 ..
drwx------. 19 systemd-bus-proxy root    4096 Jun 23 18:01 data
[vagrant@localhost ~]$ ls -al workspace/postgres/data
ls: cannot open directory workspace/postgres/data: Permission denied
[vagrant@localhost ~]$ sudo ls -al workspace/postgres/data

The postgres data directory has been created by systemd-bus-proxy. Could the group and owner of the container created folder be preventing the folder from being mapped correctly by Docker or Vagrant??

That image initializes the data without issue for me, just make sure the volume you mount is writable by the container:

$ mkdir data
$ ls -al data/
total 8
drwxr-xr-x 2 bmitch bmitch 4096 Jun 19 19:30 .
drwxr-xr-x 3 bmitch bmitch 4096 Jun 19 19:30 ..
$ chmod 777 data
$ docker run --name test-postgres \
  -e POSTGRES_PASSWORD=test123 \
  -v `pwd`/data:/var/lib/postgresql/data \
  -d postgres:9.6
$ sudo ls -al data
[sudo] password for bmitch: 
total 128
drwx------ 19    999 bmitch  4096 Jun 19 19:32 .
drwxr-xr-x  3 bmitch bmitch  4096 Jun 19 19:30 ..
drwx------  5    999 docker  4096 Jun 19 19:32 base
drwx------  2    999 docker  4096 Jun 19 19:33 global
...

Note the uid 999 is internal to the container. A named volume avoids the uid mapping and chmod to world writable part:

$ docker run --name test-postgres \
  -e POSTGRES_PASSWORD=test123 \
  -v postgres-data:/var/lib/postgresql/data \
  -d postgres:9.6

Edit: from your additions, I see you're using a host volume on docker that's running inside a Vagrant VM and mapping that volume to a share that's then mapped to a Windows host. Looking at this github thread there's a fairly common and old issue that is caused by the docker engine starting up before the VM maps the shared file systems. Restarting the docker engine inside the VM should resolve it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM