This is a Fantastic Failure article.

Did you know that the EXPOSE port declaration in Dockerfile is practically useless. Not declaring it, you can still forward a host port to any port number to the container. Not declaring it, doesn’t prevent other containers from initiating TCPIP connection using that port. It is just there for “bookkeeping”, so you can see it, explicitly there that the application uses port 80.
Did you know that the VOLUME declaration in Dockerfile, is VERY CONSEQUENTIAL! Once you declare a volume, in a Dockerfile, no changes you make in that folder after the container was started, can be committed to new image. B/c once you declare VOLUME, it HAS TO HAVE A VOLUME attached. And if you do not specify a VOLUME location, “one will be appointed to you free of charge”. It will create a un-named local volume.
FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvolThis Dockerfile results in an image that causes docker run to create a new mount point at /myvol and copy the greeting file into the newly created volume.
What this means in WordPress and MySQL containers (and most container images), is if you want data pre-populated, when you create custom containers based on the images of those products, it won’t be in those directories specified as VOLUME.
Mind you, this is desirable behavior, in actuality. 99% of people don’t want their data pushed. But, if you want to, there doesn’t seem to be a designed way to do this.
“If you start a container which creates a new volume, and the container has files or directories in the directory to be mounted such as /app/, Docker copies the directory’s contents into the volume. The container then mounts and uses the volume, and other containers which use the volume also have access to the pre-populated content.”
https://docs.docker.com/engine/storage/volumes/#populate-a-volume-using-a-container
And as far as I can tell, there is no way to get at that data that already exists already in the directory, before the volume is mounted. This should confuse a lot of people that think a volume acts like mounting a NFS file system on a unix file system, over existing folder w files in it (mounted file system is overlayed on top of existing file system, and you don’t have access to it, until the NFS file system is unmounted). That part is same. But it doesn’t prepopulate. And it doesn’t create a new mount point, if none exists.
So, if you were thinking about distributing your own container image, with data prepopulated, like I was for WordPress in
Wordpress’s /var/www/html directory, and mysql /var/lib/mysql directory, that will not work. VOLUMES are not part of the container image. And Dockerfile-type VOLUME data will always outside of the container image.
Something exotic will be needed, like putting data in the filesystem, before the image. Which I don’t think is supported out of box.
In other words: Many Docker images in docker hub are using volumes by default. What is the easiest way to save all the data inside the container (so push, and commit will contain the data)? There is a command to stop a container, change it’s Mounts settings, and start again?
I know that it is not best practice, my question is if it is possible.
TLDR: No
This article is a Fantastic Failure, b/c I let my preconceptions that VOLUME worked almost completely like mounting a NFS mount. That if you didn’t mount the volume, the directory would act like a directory. But it worked even better (for a container), and I didn’t anticipate they would give an option to image creator, to require a volume on specific directories. I actually don’t want image declared VOLUME to require explicit assignment declaration, now that I know what it does. But it seems to me that a –create-vol-if-not-spec flag acknowledging that the user has to cleanup dangling anonymous volumes after running, might be prudent.