Search code examples
dockercontainersvolume

How to remove a mount for existing container?


I'm learning docker and reading their chapter "Manage data in containers". In the "Mount a host directory as a data volume". They mentioned the following paragraph:

In addition to creating a volume using the -v flag you can also mount a directory from your Docker engine’s host into a container.

$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

This command mounts the host directory, /src/webapp, into the container at /opt/webapp. If the path /opt/webapp already exists inside the container’s image, the /src/webapp mount overlays but does not remove the pre-existing content. Once the mount is removed, the content is accessible again. This is consistent with the expected behavior of the mount command.

Experiment 1

Then when I tried to run this command and try to inspect the container, I found that that actually container doesn't even run. Then I use docker logs web and find this error:

can't open file 'app.py': [Errno 2] No such file or directory I assume that the /src/webapp mount overlays on the /opt/webapp, which there is no content.

Question 1 How can I remove this mount and check if the content is still there as the quote said?

Experiment 2

When I tried to run $ docker run -d -P --name web2 -v newvolume:/opt/webapp training/webapp python app.py I found that the container ran correctly. Then I use docker exec -it web2 /bin/bash and find that all of the existing content are still inside the /opt/webapp. I can also add more files inside here. So in this case, it looks like that the volume is not overlay but combined. If I use docker inspect web and check Mounts, then I'll see that the volume is created under /var/lib/docker/volumes/newvolume/_data

Question 2 If I give a name instead of a host-dir absolute path, then the volume will not overlay the container-dir /opt/webapp but connect the two dir together?


Solution

  • Question 1 How can I remove this mount and check if the content is still there as the quote said?

    You would create a new container without the volume mount. E.g.

    $ docker run -d -P --name web training/webapp python app.py
    

    (Theoretically it's possible to perform some privileged operations to remove the mount on a running container, but inside the container you will not normally have this permission, and it's a good practice to get into the habit of treating containers as ephemeral.)

    Question 2 If I give a name instead of a host-dir absolute path, then the volume will not overlay the container-dir /opt/webapp but connect the two dir together?

    Almost. What's happening with named volumes is that docker provides an initialization step when the volume is empty and the container is created with that volume mount. The initialization step copies the contents of the image at that directory into the volume, including all files and directories recursively, ownership, and permissions. This is very useful to running containers as a non-root user with a volume directory that the user inside the container needs to be able to write into. After that initialization has happened, future containers with the same named volume will skip the initialization, even if the image content has changed, e.g. if you add new content into the image.