(I did see this)
My problem is that, unlike with volumes, using a bind mount won’t actually copy the files from the container inside it.
I first tried this:
version: "3.8"
services:
sdfsdf:
build: .
volumes:
- ./data:/path/in/container
It didn’t work because, when setting the container up, it prioritizes the content of the folder (which is absolutely nothing) over the container’s files, and replaces them.
I then went ahead to try this:
version: "3.8"
services:
sdfsdf:
build: .
volumes:
- data:/path/in/container
volumes:
data:
driver_opts:
type: "none"
o: "bind"
device: "./data"
This looked very promising to me, only to realize, upon doing a docker-compose up
that the device
option only accepts absolute paths and no relative ones.
My question is, how can I achieve the functionality of named volumes while using bind mounts? I was thinking that maybe I could make the container create all of its files in, say, /path/in/container2
, then, when the container first gets initialized, I could do a mv /path/in/container2 /path/in/container
. But, is that a good thing to do? Can it backfire in any way? And how do I make it happen only at the first start of the container, before it gets initialized?
2
Answers
One of the selling points of volumes is that they can have their content predefined.
https://docs.docker.com/storage/volumes/#populate-a-volume-using-a-container
There’s no reason at all not to use them instead of bind-mounts if that’s what you need.
You can’t do it directly from docker, once you switch to bind mount options, those are passed directly to the kernel’s mount syscall, so it’s up to you to properly complete them.
If you want to do some automatic initialization as part of your entrypoint, that’s easy enough. I’ve done that before in an example base image. You’ll now need to maintain that code in your image, and handle the various scenarios.
For example, when restarting the container, does it overwrite the volume contents from before, potentially deleting user data? Or do you leave the volume untouched, which means the user could see old data from a previous image state if they don’t first delete the folder before starting the project? When docker initializes the folder, the logic is if there is any content in the named volume, the initialization from the image is skipped. You can also leverage files created inside of the container filesystem that will remain on a container restart but get reset to the image state on a new container. You can see the latter happening in the load-volume script with the touch command at the end: