-
Notifications
You must be signed in to change notification settings - Fork 7
Keeping a persisted directory of data from a Docker container using volumes
If a Docker container is run, the files modified during its session will not be persisted after the Docker process is shut down.
If you want to keep the changes made to its container file system locally, it can be desirable to use the host file system as 'storage' (i.e. to 'persist' the changes 'locally')
docker ps will list the processes of running docker containers with their CONTAINER_ID
This Q&A describes ways to "explore a docker container's file system"
- Snapshotting
- ssh
nsenter
More simply, since docker exec was introduced, you can docker exec <container> ls <dir path>
(which seems preferable to creating a static image)
Much like virtual machines, you can mount the host's directories in a container and these will persist unlike the rest of the container's file system.
In my case I am spinning up the image coatwork/dockerimage:latest for the 2020 Combinatorial Optimisation summer school
docker run --rm -it -p 9001:9001 coatwork/dockerimage:latestand this creates a persisted directory:
docker run --rm -it -v /home/louis/co/testing/files/:/jupyter/persist -p 9001:9001 coatwork/dockerimage:latestI knew the working directory was /jupyter/ because I looked at the Dockerfile on Docker Hub (here) and read the line:
WORKDIR /jupyterwhich is run before the Jupyter server is launched (see the sections on WORKDIR in Docker's documentation and note on best practices)
So passing /jupyter/persist as the volume location means it will be created as a directory alongside the notebook directories.
You can check the permissions for the directory with ls -ld and then convert these into the numeric code at chmod-calculator.com
sudo docker exec silly_johnson ls -ld "/jupyter/persist"⇣
drwxr-xr-x 3 1000 1000 4096 Sep 14 12:34 /jupyter/persist
gives the permissions code for the directory ("silly_johnson" is the name of the active container found by sudo docker ps)
- the three parts of the permissions are: owners, group members, other users
To make the directory writable by both host and container, you'd want to chmod +w it but that doesn't work with docker exec
- Note that if
jupyter/is used as the volume location, notjupyter/persist(which was a location I invented for this purpose), then the container will mirror that empty directory and no notebooks appear there- this might have happened due to file permission mismatch?
To set permissions, it seems you have to set them before using the directory, as I'll now demonstrate.
The following section is a demo of what doesn't work, feel free to skip to the next line break
To step into the container running Jupyter, as shown here
docker exec -it xenodochial_kilby bash(Above the container ID was silly_johnson but now it's become xenodochial_kilby)
This is a lot like ssh, and shows a command line from within the container's file system, running the bash shell.
www-data@85dd6fb1b423:/jupyter$ ls -ld ./*/
drwxr-xr-x 1 www-data www-data 4096 Aug 14 17:34 ./2020-09-14_monday/
drwxr-xr-x 1 www-data www-data 4096 Sep 9 22:15 ./2020-09-15_tuesday/
drwxr-xr-x 1 www-data www-data 4096 Aug 27 08:51 ./2020-09-16_wednesday/
drwxr-xr-x 1 www-data www-data 4096 Sep 7 10:05 ./2020-09-17_thursday/
drwxr-xr-x 1 www-data www-data 4096 Sep 9 17:58 ./2020-09-18_friday/
drwxr-xr-x 1 www-data www-data 4096 Sep 1 16:13 ./2020-09-22_tuesday/
drwxr-xr-x 1 www-data www-data 4096 Sep 7 11:14 ./2020-09-23_wednesday/
drwxr-xr-x 1 www-data www-data 4096 Sep 1 16:13 ./2020-09-24_thursday/
drwxr-xr-x 1 www-data www-data 4096 Aug 14 15:15 ./local/
drwxr-xr-x 3 1000 1000 4096 Sep 14 12:34 ./persist/
So now I'll try to change the permissions of the volume at persist/ to 777
www-data@85dd6fb1b423:/jupyter$ chmod 777 persist/
chmod: changing permissions of 'persist/': Operation not permittedIt's still not possible: you need to change it before using it.
To create a directory, you run docker volume create, however this defaults to storing the volume under
/var/lib/docker/volume/ whereas I want to store it at /home/louis/co/testing/files/.
To specify a custom location, you need to pass the -o or --opt flag to docker volume create,
and then set one of the settings to the unix mount tool (which is the "driver"
managing volumes here).
It's not made very clear how this is derived from mount exactly (docker's docs are not friendly, frustratingly, and
just say that you can find "the complete list of options" in the man pages for mount) but:
--opt device=/home/louis/co/testing/files/seems to be the way to specify a custom location in this way
docker volume list will show any volumes created, so now I'll try to create a docker volume with custom permissions